diff --git a/UnitsNet.Tests/CustomCode/ParseTests.cs b/UnitsNet.Tests/CustomCode/ParseTests.cs
index 22a662733b..37113abb0b 100644
--- a/UnitsNet.Tests/CustomCode/ParseTests.cs
+++ b/UnitsNet.Tests/CustomCode/ParseTests.cs
@@ -19,7 +19,6 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
-using System;
using System.Globalization;
using NUnit.Framework;
using UnitsNet.Units;
@@ -36,14 +35,14 @@ namespace UnitsNet.Tests.CustomCode
[TestFixture]
public class ParseTests
{
- [TestCase("1km", Result=1000)]
+ [TestCase("1km", Result = 1000)]
[TestCase("1 km", Result = 1000)]
[TestCase("1e-3 km", Result = 1)]
[TestCase("5.5 m", Result = 5.5)]
[TestCase("500,005 m", Result = 500005)]
[TestCase(null, ExpectedExceptionName = "System.ArgumentNullException")]
[TestCase("1", ExpectedExceptionName = "System.ArgumentException")]
- [TestCase("km", ExpectedExceptionName = "System.ArgumentException")]
+ [TestCase("km", ExpectedExceptionName = "UnitsNet.UnitsNetException")]
[TestCase("1 kg", ExpectedExceptionName = "UnitsNet.UnitsNetException")]
public double ParseLengthToMetersUsEnglish(string s)
{
@@ -52,6 +51,21 @@ public double ParseLengthToMetersUsEnglish(string s)
return Length.Parse(s, usEnglish).Meters;
}
+ [TestCase("1 ft 1 in", Result = 13)]
+ [TestCase("1ft 1in", Result = 13)]
+ [TestCase("1' 1\"", Result = 13)]
+ [TestCase("1'1\"", Result = 13)]
+ [TestCase("1ft1in", Result = 13)]
+ [TestCase("1ft and 1in", Result = 13)]
+ [TestCase("1ft monkey 1in", ExpectedExceptionName = "UnitsNet.UnitsNetException")]
+ [TestCase("1ft 1invalid", ExpectedExceptionName = "UnitsNet.UnitsNetException")]
+ public double ParseImperialLengthInchesUsEnglish(string s)
+ {
+ var usEnglish = CultureInfo.GetCultureInfo("en-US");
+
+ return Length.Parse(s, usEnglish).Inches;
+ }
+
/// Error parsing string.
[TestCase("5.5 m", Result = 5.5)]
[TestCase("500 005 m", Result = 500005)]
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs
index 13a1c39159..39bcaeef10 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -232,17 +233,16 @@ public double As(AccelerationUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Acceleration Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -254,41 +254,70 @@ public static Acceleration Parse(string str, IFormatProvider formatProvider = nu
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- AccelerationUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ AccelerationUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs b/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs
index da92e1910d..415bfd80fc 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -280,17 +281,16 @@ public double As(AmplitudeRatioUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static AmplitudeRatio Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -302,41 +302,70 @@ public static AmplitudeRatio Parse(string str, IFormatProvider formatProvider =
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- AmplitudeRatioUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ AmplitudeRatioUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs
index 36e0c9e2dd..fcefc4b82a 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -272,17 +273,16 @@ public double As(AngleUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Angle Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -294,41 +294,70 @@ public static Angle Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- AngleUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ AngleUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs
index ffc2e3b545..746d1ca247 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -392,17 +393,16 @@ public double As(AreaUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Area Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -414,41 +414,70 @@ public static Area Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- AreaUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ AreaUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Density.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Density.g.cs
index 0693da3b03..c0892ed6c1 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Density.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Density.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -412,17 +413,16 @@ public double As(DensityUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Density Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -434,41 +434,70 @@ public static Density Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- DensityUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ DensityUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs
index 3f44d89f11..cfcbb1e617 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -412,17 +413,16 @@ public double As(DurationUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Duration Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -434,41 +434,70 @@ public static Duration Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- DurationUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ DurationUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs b/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs
index 99328f11f4..c3cafee71e 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -332,17 +333,16 @@ public double As(ElectricCurrentUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static ElectricCurrent Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -354,41 +354,70 @@ public static ElectricCurrent Parse(string str, IFormatProvider formatProvider =
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- ElectricCurrentUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ ElectricCurrentUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs b/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs
index 54ead91545..8e7a03f632 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -312,17 +313,16 @@ public double As(ElectricPotentialUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static ElectricPotential Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -334,41 +334,70 @@ public static ElectricPotential Parse(string str, IFormatProvider formatProvider
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- ElectricPotentialUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ ElectricPotentialUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs b/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs
index 377bf7cff9..d466d08420 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -272,17 +273,16 @@ public double As(ElectricResistanceUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static ElectricResistance Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -294,41 +294,70 @@ public static ElectricResistance Parse(string str, IFormatProvider formatProvide
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- ElectricResistanceUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ ElectricResistanceUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Energy.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Energy.g.cs
index 269a18222e..07563408a0 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Energy.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Energy.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -272,17 +273,16 @@ public double As(EnergyUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Energy Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -294,41 +294,70 @@ public static Energy Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- EnergyUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ EnergyUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs
index 54b238db62..c1b6d0e565 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -292,17 +293,16 @@ public double As(FlowUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Flow Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -314,41 +314,70 @@ public static Flow Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- FlowUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ FlowUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs
index 8d18db0b1c..16e0e24240 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -372,17 +373,16 @@ public double As(ForceUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Force Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -394,41 +394,70 @@ public static Force Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- ForceUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ ForceUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs
index 10dfa22e23..3132aea747 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -312,17 +313,16 @@ public double As(FrequencyUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Frequency Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -334,41 +334,70 @@ public static Frequency Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- FrequencyUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ FrequencyUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs
index ea87e1b325..e2daeb800c 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -732,17 +733,16 @@ public double As(InformationUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Information Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -754,41 +754,70 @@ public static Information Parse(string str, IFormatProvider formatProvider = nul
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- InformationUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ InformationUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/KinematicViscosity.g.cs b/UnitsNet/GeneratedCode/UnitClasses/KinematicViscosity.g.cs
index 2172ced19c..f18649eff5 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/KinematicViscosity.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/KinematicViscosity.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -372,17 +373,16 @@ public double As(KinematicViscosityUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static KinematicViscosity Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -394,41 +394,70 @@ public static KinematicViscosity Parse(string str, IFormatProvider formatProvide
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- KinematicViscosityUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ KinematicViscosityUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs
index f2256f0fff..cd5a641b73 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -472,17 +473,16 @@ public double As(LengthUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Length Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -494,41 +494,70 @@ public static Length Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- LengthUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ LengthUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs
index cf5d3a2df1..ab78ee9fc8 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -260,17 +261,16 @@ public double As(LevelUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Level Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -282,41 +282,70 @@ public static Level Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- LevelUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ LevelUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs
index b653b3bcbd..7c52b1591c 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -552,17 +553,16 @@ public double As(MassUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Mass Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -574,41 +574,70 @@ public static Mass Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- MassUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ MassUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs
index 11e88ee66c..d2a21e49ca 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -532,17 +533,16 @@ public double As(PowerUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Power Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -554,41 +554,70 @@ public static Power Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- PowerUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ PowerUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs b/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs
index 9381ad71ad..a428bd4e9c 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -260,17 +261,16 @@ public double As(PowerRatioUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static PowerRatio Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -282,41 +282,70 @@ public static PowerRatio Parse(string str, IFormatProvider formatProvider = null
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- PowerRatioUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ PowerRatioUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs
index 2c0030051f..0b7b83095d 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -872,17 +873,16 @@ public double As(PressureUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Pressure Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -894,41 +894,70 @@ public static Pressure Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?[a-z]*)?"); // capture invalid input
+
+ var quantities = ParseWithRegex(regexString, str, formatProvider);
+ if (quantities.Count == 0)
{
- var ex = new ArgumentException(
- "Expected valid quantity and unit. Input string needs to be in the format \" or \".", "str");
- ex.Data["input"] = str;
- ex.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw ex;
+ throw new ArgumentException(
+ "Expected string to have at least one pair of quantity and unit in the format"
+ + " \"<quantity> <unit>\". Eg. \"5.5 m\" or \"1ft 2in\"");
}
+ return quantities.Aggregate((x, y) => x + y);
+ }
- try
- {
- PressureUnit unit = ParseUnit(unitString, formatProvider);
- double value = double.Parse(valueString, formatProvider);
+ ///
+ /// Parse a string given a particular regular expression.
+ ///
+ /// Error parsing string.
+ private static List ParseWithRegex(string regexString, string str, IFormatProvider formatProvider = null)
+ {
+ var regex = new Regex(regexString);
+ MatchCollection matches = regex.Matches(str.Trim());
+ var converted = new List();
- return From(value, unit);
- }
- catch (Exception e)
+ foreach (Match match in matches)
{
- var newEx = new UnitsNetException("Error parsing string.", e);
- newEx.Data["input"] = str;
- newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
- throw newEx;
+ GroupCollection groups = match.Groups;
+
+ var valueString = groups["value"].Value;
+ var unitString = groups["unit"].Value;
+ if (groups["invalid"].Value != "")
+ {
+ var newEx = new UnitsNetException("Invalid string detected: " + groups["invalid"].Value);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
+ if (valueString == "" && unitString == "") continue;
+
+ try
+ {
+ PressureUnit unit = ParseUnit(unitString, formatProvider);
+ double value = double.Parse(valueString, formatProvider);
+
+ converted.Add(From(value, unit));
+ }
+ catch (Exception ex)
+ {
+ var newEx = new UnitsNetException("Error parsing string.", ex);
+ newEx.Data["input"] = str;
+ newEx.Data["matched value"] = valueString;
+ newEx.Data["matched unit"] = unitString;
+ newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString();
+ throw newEx;
+ }
}
+ return converted;
}
///
diff --git a/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs b/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs
index d48d2184ad..77960770fa 100644
--- a/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs
+++ b/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs
@@ -20,6 +20,7 @@
// THE SOFTWARE.
using System;
+using System.Collections.Generic;
using System.Globalization;
using System.Text.RegularExpressions;
using System.Linq;
@@ -332,17 +333,16 @@ public double As(RatioUnit unit)
#region Parsing
///
- /// Parse a string of the format "<quantity> <unit>".
+ /// Parse a string with one or two quantities of the format "<quantity> <unit>".
///
///
/// Length.Parse("5.5 m", new CultureInfo("en-US"));
///
/// The value of 'str' cannot be null.
///
- /// Expected 2 words. Input string needs to be in the format "<quantity> <unit
- /// >".
+ /// Expected string to have one or two pairs of quantity and unit in the format
+ /// "<quantity> <unit>". Eg. "5.5 m" or "1ft 2in"
///
- /// Error parsing string.
public static Ratio Parse(string str, IFormatProvider formatProvider = null)
{
if (str == null) throw new ArgumentNullException("str");
@@ -354,41 +354,70 @@ public static Ratio Parse(string str, IFormatProvider formatProvider = null)
var numRegex = string.Format(@"[\d., {0}{1}]*\d", // allows digits, dots, commas, and spaces in the quantity (must end in digit)
numFormat.NumberGroupSeparator, // adds provided (or current) culture's group separator
numFormat.NumberDecimalSeparator); // adds provided (or current) culture's decimal separator
- var regexString = string.Format("(?[-+]?{0}{1}{2}{3}",
- numRegex, // capture base (integral) Quantity value
- @"(?:[eE][-+]?\d+)?)", // capture exponential (if any), end of Quantity capturing
- @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
- @"(?\S+)"); // capture Unit (non-whitespace) input
-
- var regex = new Regex(regexString);
- GroupCollection groups = regex.Match(str.Trim()).Groups;
-
- var valueString = groups["value"].Value;
- var unitString = groups["unit"].Value;
-
- if (valueString == "" || unitString == "")
+ var exponentialRegex = @"(?:[eE][-+]?\d+)?)";
+ var regexString = string.Format(@"(?:\s*(?[-+]?{0}{1}{2}{3})?{4}{5}",
+ numRegex, // capture base (integral) Quantity value
+ exponentialRegex, // capture exponential (if any), end of Quantity capturing
+ @"\s?", // ignore whitespace (allows both "1kg", "1 kg")
+ @"(?[^\s\d,]+)", // capture Unit (non-whitespace) input
+ @"(and)?,?", // allow "and" & "," separators between quantities
+ @"(?