Regular expressions can be a good way of processing text input in situations like this. Your current process finds every digit in the input string, concatenates it together, and then parses the result.
I doubt that this is a good solution because it makes examples like: "There are 10 people arriving at 9pm" parse as 109
. Is that what you want?
Even then, Regular expressions are probably a good solution:
str = Regex.Replace(str, @"[.\D+]", "");
In str
, replace all non-digits with "" (i.e. remove any non-digits).
Your code will still fail with an exception for input like "Hello", which has no digits, because the ToDecimal
call will fail. Values with multiple .
characters will also be interesting...
Additionally, your code does not support negative input values. This can be a trick to accomplish, but, again, using regular expressions, it is not horrendous.
Finally, I feel you should only be parsing the first set of decimal-like digis in the input, not all of them.
Putting this all together, I would have:
- use regex
- parse the first set of digits
- accept negative inputs
And use the code:
public static Decimal ExtractDecimalFromString(string str)
{
Regex digits = new Regex(@"^\D*?((-?(\d+(\.\d+)?))|(-?\.\d+)).*");
Match mx = digits.Match(str);
//Console.WriteLine("Input {0} - Digits {1} {2}", str, mx.Success, mx.Groups);
return mx.Success ? Convert.ToDecimal(mx.Groups[1].Value) : 0;
}
I have put this, with some test cases, in this Ideone here;
"1 day 3 people bought 5 beers for 8 dollars"
. \$\endgroup\$