Reputation: 2939
I have the following string:
string value = "123.456L";
What is the best way to parse this string into a string and a double:
double number = 123.456;
string measure = "L"
Instead of the L, we could also have something else, like oz
, m/s
, liter
, kilograms
, etc
Upvotes: 4
Views: 3770
Reputation: 8668
You might want to take a look at Units.NET on GitHub and NuGet. It supports parsing abbreviations in different cultures, but it is still on my TODO list to add support for parsing combinations of numbers and units. I have already done this on a related project, so it should be straight-forward to add.
Update Apr 2015: You can now parse units and values by Length.Parse("5.3 m");
and similar for other units.
Upvotes: 1
Reputation: 11
You can try this:
string ma = Regex.Match(name, @"((\d\s)|(\d+\s)|(\d+)|(\d+\.\d+\s))(g\s|kg\s|ml\s)").Value;
this will match:
40 g , 40g , 12.5 g , 1 kg , 2kg , 150 ml ....
Upvotes: 0
Reputation: 717
Simply spoken: look for all characters that are 0..9 or . and trim them to a new string, then have last part in second string. In a minute I cann give code.
Edit: Yes, I meant digits 0-9, corrected it. But easier is to get index of last number and ignore stuff before for the trimming.
Upvotes: 0
Reputation: 2458
You could do it with a regex
using System.Text.RegularExpression;
Regex reg = new Regex(@"([\d|\.]*)(\w*)");
string value = "123.4L";
MatchCollection matches = reg.Matches(value);
foreach (Match match in matches)
{
if (match.Success)
{
GroupCollection groups = match.Groups;
Console.WriteLine(groups[1].Value); // will be 123.4
Console.WriteLine(groups[2].Value); // will be L
}
}
So what this will do is look for a 0 or more digits or "." and then group them and then look for any character (0 or more). You can then get the groups from each match and get the value. This will work if you want to change the type of measurement and will work if you don't have a decimal point either.
Edit: It is important to note that you must use groups[1] for the first group and groups[2] for the second group. If you use group[0] it will display the original string.
Upvotes: 1
Reputation: 17346
I'd do it like this:
public bool TryParseUnit ( string sValue, out double fValue, out string sUnit )
{
fValue = 0;
sUnit = null;
if ( !String.IsNullOrEmpty ( sValue ) )
{
sUnit = GetUnit ( sValue );
if ( sUnit != null )
{
return ( Double.TryParse ( sValue.Substring ( sValue.Length - sUnit.Length ),
out fValue );
}
}
return ( false );
}
private string GetUnit ( string sValue )
{
string sValue = sValue.SubString ( sValue.Length - 1 );
switch ( sValue.ToLower () )
{
case "l":
return ( "L" );
}
return ( null );
}
I know it's more complicated than the other answers but this way you can also validate the data during parsing and discard invalid input.
Upvotes: 1
Reputation: 726909
Assuming that the units of measure are always expressed as a single character at the back of the string, you can do this:
string value = "123.456L";
var pos = value.LastIndexOfAny("0123456789".ToCharArray());
double number = double.Parse(value.Substring(0, pos+1));
string measure = value.Substring(pos+1);
Upvotes: 9
Reputation: 68717
Based on the comment explaining the input, I'd use Regex.
double number = double.Parse(Regex.Match(value, @"[\d.]+").Value);
string measure = value.Replace(number.ToString(), "");
The regex [\d.]
will match any number or .
, the +
means it must be for 1 or more matches.
Upvotes: 7