diff --git a/Src/Scripts/Include-GenerateUnitClassSourceCode.ps1 b/Src/Scripts/Include-GenerateUnitClassSourceCode.ps1 index 23edfc9a56..b2346a374a 100644 --- a/Src/Scripts/Include-GenerateUnitClassSourceCode.ps1 +++ b/Src/Scripts/Include-GenerateUnitClassSourceCode.ps1 @@ -34,6 +34,7 @@ function GenerateUnitClassSourceCode($unitClass) using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -278,11 +279,30 @@ namespace UnitsNet public static $className Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -290,17 +310,7 @@ namespace UnitsNet try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - $unitEnumName unit = unitSystem.Parse<$unitEnumName>(unitString); + $unitEnumName unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -314,6 +324,32 @@ namespace UnitsNet } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static $unitEnumName ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse<$unitEnumName>(str.Trim()); + + if (unit == $unitEnumName.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized $unitEnumName."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs index 8b258d9410..13a1c39159 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Acceleration.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -245,11 +246,30 @@ public double As(AccelerationUnit unit) public static Acceleration Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -257,17 +277,7 @@ public static Acceleration Parse(string str, IFormatProvider formatProvider = nu try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - AccelerationUnit unit = unitSystem.Parse(unitString); + AccelerationUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -281,6 +291,32 @@ public static Acceleration Parse(string str, IFormatProvider formatProvider = nu } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static AccelerationUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == AccelerationUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized AccelerationUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs index 52289282f0..da92e1910d 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/AmplitudeRatio.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -293,11 +294,30 @@ public double As(AmplitudeRatioUnit unit) public static AmplitudeRatio Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -305,17 +325,7 @@ public static AmplitudeRatio Parse(string str, IFormatProvider formatProvider = try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - AmplitudeRatioUnit unit = unitSystem.Parse(unitString); + AmplitudeRatioUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -329,6 +339,32 @@ public static AmplitudeRatio Parse(string str, IFormatProvider formatProvider = } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static AmplitudeRatioUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == AmplitudeRatioUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized AmplitudeRatioUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs index dbe5b04253..36e0c9e2dd 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Angle.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -285,11 +286,30 @@ public double As(AngleUnit unit) public static Angle Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -297,17 +317,7 @@ public static Angle Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - AngleUnit unit = unitSystem.Parse(unitString); + AngleUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -321,6 +331,32 @@ public static Angle Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static AngleUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == AngleUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized AngleUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs index 0c3b5283cc..ffc2e3b545 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Area.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -405,11 +406,30 @@ public double As(AreaUnit unit) public static Area Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -417,17 +437,7 @@ public static Area Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - AreaUnit unit = unitSystem.Parse(unitString); + AreaUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -441,6 +451,32 @@ public static Area Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static AreaUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == AreaUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized AreaUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs index d99ea9847b..3f44d89f11 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Duration.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -425,11 +426,30 @@ public double As(DurationUnit unit) public static Duration Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -437,17 +457,7 @@ public static Duration Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - DurationUnit unit = unitSystem.Parse(unitString); + DurationUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -461,6 +471,32 @@ public static Duration Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static DurationUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == DurationUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized DurationUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs index c40f0a3da1..99328f11f4 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricCurrent.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -345,11 +346,30 @@ public double As(ElectricCurrentUnit unit) public static ElectricCurrent Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -357,17 +377,7 @@ public static ElectricCurrent Parse(string str, IFormatProvider formatProvider = try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - ElectricCurrentUnit unit = unitSystem.Parse(unitString); + ElectricCurrentUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -381,6 +391,32 @@ public static ElectricCurrent Parse(string str, IFormatProvider formatProvider = } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static ElectricCurrentUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == ElectricCurrentUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized ElectricCurrentUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs index 81db036507..54ead91545 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricPotential.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -325,11 +326,30 @@ public double As(ElectricPotentialUnit unit) public static ElectricPotential Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -337,17 +357,7 @@ public static ElectricPotential Parse(string str, IFormatProvider formatProvider try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - ElectricPotentialUnit unit = unitSystem.Parse(unitString); + ElectricPotentialUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -361,6 +371,32 @@ public static ElectricPotential Parse(string str, IFormatProvider formatProvider } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static ElectricPotentialUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == ElectricPotentialUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized ElectricPotentialUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs index 8875f2d611..377bf7cff9 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/ElectricResistance.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -285,11 +286,30 @@ public double As(ElectricResistanceUnit unit) public static ElectricResistance Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -297,17 +317,7 @@ public static ElectricResistance Parse(string str, IFormatProvider formatProvide try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - ElectricResistanceUnit unit = unitSystem.Parse(unitString); + ElectricResistanceUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -321,6 +331,32 @@ public static ElectricResistance Parse(string str, IFormatProvider formatProvide } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static ElectricResistanceUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == ElectricResistanceUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized ElectricResistanceUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs index ccc50277e1..54b238db62 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Flow.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -305,11 +306,30 @@ public double As(FlowUnit unit) public static Flow Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -317,17 +337,7 @@ public static Flow Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - FlowUnit unit = unitSystem.Parse(unitString); + FlowUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -341,6 +351,32 @@ public static Flow Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static FlowUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == FlowUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized FlowUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs index 5afa6fcfcb..4bbac8ed19 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Force.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -365,11 +366,30 @@ public double As(ForceUnit unit) public static Force Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -377,17 +397,7 @@ public static Force Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - ForceUnit unit = unitSystem.Parse(unitString); + ForceUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -401,6 +411,32 @@ public static Force Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static ForceUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == ForceUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized ForceUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs index 6a19bcd0d4..10dfa22e23 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Frequency.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -325,11 +326,30 @@ public double As(FrequencyUnit unit) public static Frequency Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -337,17 +357,7 @@ public static Frequency Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - FrequencyUnit unit = unitSystem.Parse(unitString); + FrequencyUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -361,6 +371,32 @@ public static Frequency Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static FrequencyUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == FrequencyUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized FrequencyUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs index b3c6dca3bb..ea87e1b325 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Information.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -745,11 +746,30 @@ public double As(InformationUnit unit) public static Information Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -757,17 +777,7 @@ public static Information Parse(string str, IFormatProvider formatProvider = nul try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - InformationUnit unit = unitSystem.Parse(unitString); + InformationUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -781,6 +791,32 @@ public static Information Parse(string str, IFormatProvider formatProvider = nul } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static InformationUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == InformationUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized InformationUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs index bd0f6d964e..f2256f0fff 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Length.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -485,11 +486,30 @@ public double As(LengthUnit unit) public static Length Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -497,17 +517,7 @@ public static Length Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - LengthUnit unit = unitSystem.Parse(unitString); + LengthUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -521,6 +531,32 @@ public static Length Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static LengthUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == LengthUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized LengthUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs index 252ce3722c..cf5d3a2df1 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Level.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -273,11 +274,30 @@ public double As(LevelUnit unit) public static Level Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -285,17 +305,7 @@ public static Level Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - LevelUnit unit = unitSystem.Parse(unitString); + LevelUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -309,6 +319,32 @@ public static Level Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static LevelUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == LevelUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized LevelUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs index 7a62c295fb..90993edd74 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Mass.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -545,11 +546,30 @@ public double As(MassUnit unit) public static Mass Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -557,17 +577,7 @@ public static Mass Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - MassUnit unit = unitSystem.Parse(unitString); + MassUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -581,6 +591,32 @@ public static Mass Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static MassUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == MassUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized MassUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs index 66747420e8..9a90ab0312 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Power.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -445,11 +446,30 @@ public double As(PowerUnit unit) public static Power Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -457,17 +477,7 @@ public static Power Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - PowerUnit unit = unitSystem.Parse(unitString); + PowerUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -481,6 +491,32 @@ public static Power Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static PowerUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == PowerUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized PowerUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs index a0619b6c1d..9381ad71ad 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/PowerRatio.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -273,11 +274,30 @@ public double As(PowerRatioUnit unit) public static PowerRatio Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -285,17 +305,7 @@ public static PowerRatio Parse(string str, IFormatProvider formatProvider = null try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - PowerRatioUnit unit = unitSystem.Parse(unitString); + PowerRatioUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -309,6 +319,32 @@ public static PowerRatio Parse(string str, IFormatProvider formatProvider = null } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static PowerRatioUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == PowerRatioUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized PowerRatioUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs index 30817af35f..4ae1cbdbb8 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Pressure.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -465,11 +466,30 @@ public double As(PressureUnit unit) public static Pressure Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -477,17 +497,7 @@ public static Pressure Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - PressureUnit unit = unitSystem.Parse(unitString); + PressureUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -501,6 +511,32 @@ public static Pressure Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static PressureUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == PressureUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized PressureUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs index 193d867aaa..d48d2184ad 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Ratio.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -345,11 +346,30 @@ public double As(RatioUnit unit) public static Ratio Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -357,17 +377,7 @@ public static Ratio Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - RatioUnit unit = unitSystem.Parse(unitString); + RatioUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -381,6 +391,32 @@ public static Ratio Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static RatioUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == RatioUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized RatioUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/RotationalSpeed.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/RotationalSpeed.g.cs index f87b46d4fd..f8e8be0a1d 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/RotationalSpeed.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/RotationalSpeed.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -265,11 +266,30 @@ public double As(RotationalSpeedUnit unit) public static RotationalSpeed Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -277,17 +297,7 @@ public static RotationalSpeed Parse(string str, IFormatProvider formatProvider = try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - RotationalSpeedUnit unit = unitSystem.Parse(unitString); + RotationalSpeedUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -301,6 +311,32 @@ public static RotationalSpeed Parse(string str, IFormatProvider formatProvider = } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static RotationalSpeedUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == RotationalSpeedUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized RotationalSpeedUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Speed.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Speed.g.cs index 846512377c..9afbec9a24 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Speed.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Speed.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -325,11 +326,30 @@ public double As(SpeedUnit unit) public static Speed Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -337,17 +357,7 @@ public static Speed Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - SpeedUnit unit = unitSystem.Parse(unitString); + SpeedUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -361,6 +371,32 @@ public static Speed Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static SpeedUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == SpeedUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized SpeedUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Temperature.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Temperature.g.cs index 339e2a5b76..0f71d7a087 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Temperature.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Temperature.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -385,11 +386,30 @@ public double As(TemperatureUnit unit) public static Temperature Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -397,17 +417,7 @@ public static Temperature Parse(string str, IFormatProvider formatProvider = nul try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - TemperatureUnit unit = unitSystem.Parse(unitString); + TemperatureUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -421,6 +431,32 @@ public static Temperature Parse(string str, IFormatProvider formatProvider = nul } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static TemperatureUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == TemperatureUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized TemperatureUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Torque.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Torque.g.cs index bdbf5eb6bd..e1700cca7f 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Torque.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Torque.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -245,11 +246,30 @@ public double As(TorqueUnit unit) public static Torque Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -257,17 +277,7 @@ public static Torque Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - TorqueUnit unit = unitSystem.Parse(unitString); + TorqueUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -281,6 +291,32 @@ public static Torque Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static TorqueUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == TorqueUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized TorqueUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Src/UnitsNet/GeneratedCode/UnitClasses/Volume.g.cs b/Src/UnitsNet/GeneratedCode/UnitClasses/Volume.g.cs index e1692d9f3f..4827012d0a 100644 --- a/Src/UnitsNet/GeneratedCode/UnitClasses/Volume.g.cs +++ b/Src/UnitsNet/GeneratedCode/UnitClasses/Volume.g.cs @@ -21,6 +21,7 @@ using System; using System.Globalization; +using System.Text.RegularExpressions; using System.Linq; using JetBrains.Annotations; using UnitsNet.Units; @@ -625,11 +626,30 @@ public double As(VolumeUnit unit) public static Volume Parse(string str, IFormatProvider formatProvider = null) { if (str == null) throw new ArgumentNullException("str"); - string[] words = str.Split(new[] {" "}, StringSplitOptions.RemoveEmptyEntries); - if (words.Length < 2) + + var numFormat = formatProvider != null ? + (NumberFormatInfo) formatProvider.GetFormat(typeof (NumberFormatInfo)) : + NumberFormatInfo.CurrentInfo; + + 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 ex = new ArgumentException( - "Expected two or more words. Input string needs to be in the format \" \".", "str"); + "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; @@ -637,17 +657,7 @@ public static Volume Parse(string str, IFormatProvider formatProvider = null) try { - // Unit string is the last word, since units added so far don't contain spaces. - // Value string is everything else since number formatting can contain spaces. - string[] allWordsButLast = words.Take(words.Length - 1).ToArray(); - string lastWord = words[words.Length - 1]; - - string unitString = lastWord; - string valueString = string.Join(" ", allWordsButLast); - - var unitSystem = UnitSystem.GetCached(formatProvider); - - VolumeUnit unit = unitSystem.Parse(unitString); + VolumeUnit unit = ParseUnit(unitString, formatProvider); double value = double.Parse(valueString, formatProvider); return From(value, unit); @@ -661,6 +671,32 @@ public static Volume Parse(string str, IFormatProvider formatProvider = null) } } + /// + /// Parse a unit string. + /// + /// + /// Length.ParseUnit("m", new CultureInfo("en-US")); + /// + /// The value of 'str' cannot be null. + /// Error parsing string. + public static VolumeUnit ParseUnit(string str, IFormatProvider formatProvider = null) + { + if (str == null) throw new ArgumentNullException("str"); + var unitSystem = UnitSystem.GetCached(formatProvider); + + var unit = unitSystem.Parse(str.Trim()); + + if (unit == VolumeUnit.Undefined) + { + var newEx = new UnitsNetException("Error parsing string. The unit is not a recognized VolumeUnit."); + newEx.Data["input"] = str; + newEx.Data["formatprovider"] = formatProvider == null ? null : formatProvider.ToString(); + throw newEx; + } + + return unit; + } + #endregion /// diff --git a/Tests/CustomCode/ParseTests.cs b/Tests/CustomCode/ParseTests.cs index 9e6a9b52bd..22a662733b 100644 --- a/Tests/CustomCode/ParseTests.cs +++ b/Tests/CustomCode/ParseTests.cs @@ -19,8 +19,10 @@ // 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; namespace UnitsNet.Tests.CustomCode { @@ -34,24 +36,57 @@ namespace UnitsNet.Tests.CustomCode [TestFixture] public class ParseTests { - /// Error parsing string. - [Test] - public void ParseWithUsEnglishCulture() + [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("1 kg", ExpectedExceptionName = "UnitsNet.UnitsNetException")] + public double ParseLengthToMetersUsEnglish(string s) { var usEnglish = CultureInfo.GetCultureInfo("en-US"); - Assert.AreEqual(5.5, Length.Parse("5.5 m", usEnglish).Meters); - Assert.AreEqual(500005, Length.Parse("500,005 m", usEnglish).Meters); + + return Length.Parse(s, usEnglish).Meters; } /// Error parsing string. - [Test] - public void ParseWithCultureUsingSpaceAsThousandSeparators() + [TestCase("5.5 m", Result = 5.5)] + [TestCase("500 005 m", Result = 500005)] + [TestCase("500.005.050,001 m", ExpectedExceptionName = "UnitsNet.UnitsNetException")] // quantity doesn't match number format + public double ParseWithCultureUsingSpaceAsThousandSeparators(string s) { - var numberFormat = (NumberFormatInfo) CultureInfo.InvariantCulture.NumberFormat.Clone(); + var numberFormat = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone(); numberFormat.NumberGroupSeparator = " "; + numberFormat.NumberDecimalSeparator = "."; + + return Length.Parse(s, numberFormat).Meters; + } + + /// Error parsing string. + [TestCase("5,5 m", Result = 5.5)] + [TestCase("500.005.050,001 m", Result = 500005050.001)] + [TestCase("5.555 m", Result = 5555)] // dot is group separator not decimal + [TestCase("500 005 m", ExpectedExceptionName = "UnitsNet.UnitsNetException")] // quantity doesn't match number format + public double ParseWithCultureUsingDotAsThousandSeparators(string s) + { + var numberFormat = (NumberFormatInfo)CultureInfo.InvariantCulture.NumberFormat.Clone(); + numberFormat.NumberGroupSeparator = "."; + numberFormat.NumberDecimalSeparator = ","; + + return Length.Parse(s, numberFormat).Meters; + } + + [TestCase("m", Result = LengthUnit.Meter)] + [TestCase("kg", ExpectedExceptionName = "UnitsNet.UnitsNetException")] + [TestCase(null, ExpectedExceptionName = "System.ArgumentNullException")] + public LengthUnit ParseLengthUnitUsEnglish(string s) + { + var usEnglish = CultureInfo.GetCultureInfo("en-US"); - Assert.AreEqual(5.5, Length.Parse("5.5 m", numberFormat).Meters); - Assert.AreEqual(500005, Length.Parse("500 005 m", numberFormat).Meters); + return Length.ParseUnit(s, usEnglish); } } } \ No newline at end of file