正则表达式(.NET)验证任何实数

时间:2016-03-08 12:39:00

标签: regex validation floating-point numbers

我正在研究一种独特的正则表达式规则,能够以两种不同的格式验证任何实数:

点(千)和逗号(十进制)

123 ; 1.234.567 ; 12.345.678 ; 123.456.789 ; 1.234.567,89 ; 1.234,56789 ; 1,2 ; 0,123

逗号(千位)和点(十进制)

1,234,567 ; 12,345,678 ; 123,456,789 ; 1,234,567.89 ; 1,234.56789 ; 1.2 ; 0.123

还有一些其他限制要注意:数字可以在短语的中间,它可以在开头和潜在(e,exp,^)有标记(+, - ,+ / - ,±)最后。

我已经为此目的创建了一个帖子,最终解决方案就在这里:

(^|\s)[±+-]?\d{1,3}(?:(e|E|exp)\d+)?($|\s)|(^|\s)[±+-]?(?:([1-9]{1,3}(?:\.\d{3})*|[0])(?:,\d*)?(?:(e|E|exp)\d+)?)($|\s)|(^|\s)[±+-]?(?:([1-9]{1,3}(?:,\d{3})*|[0])(?:\.\d*)?(?:(e|E|exp)\d+)?)($|\s) 

到目前为止一切正常。但是,当数字位于以点(。)或逗号(,)或任何其他字符结尾的短语的末尾时,我发现了一个问题。它不再检测到数字。

简单的测试用例:“我的数字是123,456,789.89,0.123和123.456.789,89。”

请注意,解决此问题的唯一方法是在数字旁边添加空格。我试图创建一个替换正则表达式规则,以在数字和下一个字符之间添加一个空格。没有成功......

有人可以再次帮助我吗?

2 个答案:

答案 0 :(得分:1)

我建议将($|\s)的尾随边界调整为(?=[,.]*(?:$|\s))之类的前瞻,如果跟随.,,将会检查(但不会消费)在数字后面有一个空格或字符串结尾:

(?<=^|\s)[±+-]?\d{1,3}(?:(?:[eE](?:xp)?)\d+)?(?=[.,]*(?:$|\s))|(?<=^|\s)[±+-]?‌​(?:(?:[1-9]{1,3}(?:\.\d{3})*|[0])(?:,\d*)?(?:(?:[eE](?:xp)?)\d+)?)(?=[.,]*(?:$|\s‌​))|(?<=^|\s)[±+-]?(?:(?:[1-9]{1,3}(?:,\d{3})*|0)(?:\.\d*)?(?:(?:[eE](?:xp)?)\d+)?‌​)(?=[.,]*(?:$|\s))

您还可以通过将(e|E|exp)替换为(?:[eE](?:xp)?来缩短代码并进行一些增强。所有非捕获组都可以转换为捕获组,但使用RegexOptions.ExplicitCapture,您仍然可以获得干净的Match对象。

(?<=^|\s)[±+-]?\d{1,3}([eE](xp)?\d+)?(?=[.,]*($|\s))|(?<=^|\s)[±+-]?(([1-9]{1,3}(\.\d{3})*|0)(,\d*)?([eE](xp)?\d+)?)(?=[.,]*($|\s))|(?<=^|\s)[±+-]?(([1-9]{1,3}(,\d{3})*|0)(\.\d*)?([eE](xp)?\d+)?)(?=[.,]*($|\s))

请参阅regex demo

enter image description here

您还可以添加RegexOptions.Ignorecase标记,并将[eE](xp)?替换为e(xp)?,以进一步缩短模式。

答案 1 :(得分:0)

您可以尝试替换

\.$  (dot at the line end)

\s$  (whitespace at the line end)

那应该可以解决你的问题。祝你好运。