Can anybody provide an algorithm that checks whether an input string is a decimal number in correct shape and form?
Rules of correct shape and form:
- At most two decimal places.
- For all practical purposes, the largest number is 99,999,999.99
- The integral part can use a space, or a comma, or a dot for a group separator.
- The decimal part can use a comma, or a dot for a separator.
Examples of correct shape and form:
1,234,567.89 // English style 开发者_Python百科1.234.567,89 // French style 1 234 567,89 // German style 1234567.89 // English mathematical style 1234567,89 // European mathematical style 12.00 12.0 12
Please, resist your temptation to propose Decimal.Parse or Decimal.TryParse. Either method merrily accepts strings such as “1,2,3,4”, which is not what I want.
I answered a very similar question on Friday, and the regex to do this is going to be more complicated than you think. I strongly suggest setting up a separate regex for each style - not because it can't be done in one line, but because a one-liner for this is going to be big and pretty tough to maintain.
Here are the patterns I'd use:
English: ^[-+]?\d{1,3}(,\d{3})*(\.\d+)?$
French: ^[-+]?\d{1,3}(\.\d{3})*(,\d+)?$
German: ^[-+]?\d{1,3}(\s\d{3})*(,\d+)?$
English mathematical: ^[-+]?\d+(\.\d+)?$
European mathematical: ^[-+]?\d+(,\d+)?$
These can be combined into something like:
^[-+]?(\d{1,3}((,\d{3})*(\.\d+)?|([.\s]\d{3})*(,\d+)?)|\d+([,\.]\d+)?)$
Hopefully that one-liner is appropriately terrifying to you. This is a very common, important task, but it's also one that's more complicated than it appears.
Tested at Rubular with your example inputs: http://rubular.com/r/Dipvyrf6C8 (note that I made the groups non-capturing for clarity of the results).
Edit: Added [-+]?
clause to allow for negative numbers.
use this Simple regular expression for a decimal with a precision of 2
If it's guaranteed that there will be a decimal part, then one way to do it would be:
var s = "1 334 567,80";
var decimalPart = s.Split(',', '.').Last();
var integerPart = s.Substring(0, s.Length - decimalPart.Length - 1);
integerPart = integerPart.Replace(",", string.Empty).Replace(".", string.Empty)
.Replace(" ", string.Empty);
var decimalValue = decimal.Parse(integerPart + "." + decimalPart,
CultureInfo.InvariantCulture);
If the decimal part is optional, I 'm not sure if you can unambiguously parse this format.
精彩评论