正则表达式匹配逗号分隔的数字与可选的小数部分

Posted

技术标签:

【中文标题】正则表达式匹配逗号分隔的数字与可选的小数部分【英文标题】:RegEx to match comma separated numbers with optional decimal part 【发布时间】:2010-12-06 15:56:17 【问题描述】:

我有一个正则表达式,它匹配给定多行文本中逗号分隔的数字和可选的两位小数部分。

/(?<=\s|^)\d1,3(,\d3)*(\.\d2)?(?=\s|$)/m

成功匹配 1、12、12.34、12,345.67 等字符串。如何修改它以匹配只有小数部分的数字,如@9​​87654323@?

编辑:澄清一下 - 我想修改正则表达式,使其匹配 1212.34.34

我正在寻找“独立”的有效数字。即,边界是空格或行/字符串的开始/结束的数字字符串。

【问题讨论】:

在这里会很酷,逗号是十进制分隔符,点有时用作千位分隔符(尽管更常见的是空格)^^ Oskar,这只是纯粹的邪恶:D 虽然对于正则表达式来说非常有趣:D @Oskar 我正要问你到底住在哪里。但显然有很多地方人们使用逗号作为小数分隔符en.wikipedia.org/wiki/… 我现在什至不想考虑那部分。即使是正常的符号也足以让我头疼:) 检查@Mez 的答案。他涵盖了这两种情况。 【参考方案1】:

(@"^((([0-9]+)(.([0-9]+))?)(\,(([0-9]+)(.([0-9] +))?))*)$")

这适用于逗号分隔的整数或逗号分隔的十进制数字。

示例: 快乐的场景: 案例 1) 9,10 案例2) 10.1,11,12,15,15.2 案例 3) 9.8 案例 4) 9

悲伤的场景: 案例 1) 2..7 案例 2) 2,,7 案例 3) 2. 案例 4) 7, 案例 5) , 案例 6) . 案例 7) .2 案例 8) ,2

【讨论】:

OP 声明他们希望数字之间有空格,而不是逗号。【参考方案2】:

This answer对这个问题的处理比较全面。

【讨论】:

【参考方案3】:

这个:

\d1,3(,\d3)*(\.\d\d)?|\.\d\d

匹配以下所有数字:

1
12
.99
12.34 
12,345.67
999,999,999,999,999.99

如果您想排除诸如123a(例如街道地址)或123.123(小数点后两位以上的数字)之类的数字,请尝试:

(?<=\s|^)(\d1,3(,\d3)*(\.\d\d)?|\.\d\d)(?=\s|$)

一个小演示(我猜你正在使用 php):

$text = "666a 1 fd 12 dfsa .99 fds 12.34 dfs 12,345.67 er 666.666 er 999,999,999,999,999.99";
$number_regex = "/(?<=\s|^)(?:\d1,3(?:,\d3)*(?:\.\d\d)?|\.\d\d)(?=\s|$)/";
if(preg_match_all($number_regex, $text, $matches)) 
  print_r($matches);

将输出:

Array
(
    [0] => Array
        (
            [0] => 1
            [1] => 12
            [2] => .99
            [3] => 12.34
            [4] => 12,345.67
            [5] => 999,999,999,999,999.99
        )

)

请注意,它会忽略字符串666a666.666

【讨论】:

但这也匹配14.中的14145.2中的1451,344.123中的1,344.12 查看我对单词边界的评论。 我正在使用 actionscript,显然. 被视为单词边界,因此它仍然匹配asd 14. asd 中的14。我已经尝试过\b 并发现了这个问题,那时我选择使用从另一个 SO 线程获得的环顾四周。顺便说一句,如果你还记得的话,我是从你在***.com/questions/1547574/regex-for-prices/… 中给我的正则表达式开始的 这样,没有区别,但是当这样做时:^a|b$ 它匹配字符串开头的a,或结尾的b。而^(a|b)$ 表示:ab 示例:a(b|c)|(d|e)f 将匹配 ab 或 df,但不匹配 abf,而 a((b|c)|(d|e))f 将匹配 abf,而不是 df 或 ab【参考方案4】:
/(?<=\s|^)(\d1,3(,\d3)*(\.\d2)?|\.(\d2))(?=\s|$)/m

或者考虑到一些国家/地区。用作千位分隔符, , 用作小数分隔符

/(?<=\s|^)(\d1,3(,\d3)*(\.\d2)?|\d1,3(\.\d3)*(,\d2)?|\.(\d2)|,(\d2))(?=\s|$)/m

用于国际化的疯狂正则表达式

/((?<=\s)|(?<=^))(((\d1,3)((,\d3)|(\.\d3))*(((?<=(,\d3))(\.\d2))|((?<=(\.\d3))(,\d2))|((?<!((,\d3)|(\.\d3)))([\.,]\d2))))|([\.,]\d2))(?=\s|$)/m

匹配

14.23
14,23
114,114,114.23
114.114.114,23

不匹配

14.
114,114,114,23
114.114.144.23
,
.
<empty line>

【讨论】:

([0-9,\.]) 匹配单个字符,开始。即使你添加一个 + 它也会匹配,等等。 第一个正则表达式将整个内容括在括号中,如(fixed.decimal|.decimal)/(?&lt;=\s|^)(\d1,3(,\d3)*(\.\d2)?)|(\.\d2)(?=\s|$)/,将它们放在单独的括号中,如(fixed.decimal)|(.decimal) 有什么区别? (除了第二个在14. 中匹配14 改写最后一条评论,为什么(fixed.decimal)|(.decimal) 不起作用?我是否缺少任何运算符优先级? 啊,这取决于你有什么。 a(fixed.decimal)|(.decimal)ba((fixed.deciman)|(.decimal))b 不同 在这种情况下,没有。由于向后/向前看是不匹配的。在向后或向前看不匹配的情况下,括号用于限制或的边界。

以上是关于正则表达式匹配逗号分隔的数字与可选的小数部分的主要内容,如果未能解决你的问题,请参考以下文章

正则表达式 可以输入负数、正数、小数(小数保留一位)。

用逗号作为小数分隔符的数字的 Google 表单正则表达式

java 正则表达式匹配字符串,包含没有数字的单词,并且可以选择用逗号分隔

使用正则表达式匹配多个逗号分隔的单词

正则表达式验证序列

只有在字符串中找到一组数字时,C# 正则表达式才匹配