验证输入字符串是有效的十进制数

时间:2011-05-08 12:45:12

标签: c#

任何人都可以提供一种算法来检查输入字符串是否是正确形状和形式的十进制数?

正确形状和形式的规则:

  1. 最多两位小数。
  2. 出于所有实际目的,最大数字是99,999,999.99
  3. 整体部分可以使用空格,逗号或点作为组分隔符。
  4. 小数部分可以使用逗号或点作为分隔符。
  5. 正确的形状和形式的例子:

    1,234,567.89   // English style
    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
    

    请抵制你提出Decimal.Parse或Decimal.TryParse的诱惑。这两种方法都快乐地接受诸如“1,2,3,4”之类的字符串,这不是我想要的。

3 个答案:

答案 0 :(得分:5)

I answered a very similar question on Friday,执行此操作的正则表达式将比您想象的更复杂。我强烈建议为每种风格设置一个单独的正则表达式 - 不是因为它不能在一行中完成,而是因为这样做的单行程很大并且很难维护。

以下是我使用的模式:

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+)?$

这些可以合并为:

^[-+]?(\d{1,3}((,\d{3})*(\.\d+)?|([.\s]\d{3})*(,\d+)?)|\d+([,\.]\d+)?)$

希望单线对你来说是可怕的。这是一项非常常见的重要任务,但它也比看起来更复杂。

使用您的示例输入在Rubular上进行测试:http://rubular.com/r/Dipvyrf6C8(请注意,为了清晰显示结果,我将这些组设置为非捕获。)

修改:添加了[-+]?子句以允许使用负数。

答案 1 :(得分:0)

答案 2 :(得分:0)

如果确保作为小数部分,那么一种方法是:

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);

如果小数部分是可选的,我不确定你是否可以明确地解析这种格式。