我正在研究一种独特的正则表达式规则,能够以两种不同的格式验证任何实数:
点(千)和逗号(十进制)
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。”
请注意,解决此问题的唯一方法是在数字旁边添加空格。我试图创建一个替换正则表达式规则,以在数字和下一个字符之间添加一个空格。没有成功......
有人可以再次帮助我吗?
答案 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
您还可以添加RegexOptions.Ignorecase
标记,并将[eE](xp)?
替换为e(xp)?
,以进一步缩短模式。
答案 1 :(得分:0)
您可以尝试替换
\.$ (dot at the line end)
带
\s$ (whitespace at the line end)
那应该可以解决你的问题。祝你好运。