通过正则表达式获取逗号分隔的数字

Posted

技术标签:

【中文标题】通过正则表达式获取逗号分隔的数字【英文标题】:Fetch comma separated numbers by regex 【发布时间】:2022-01-08 05:32:14 【问题描述】:

我需要使用 Ruby String#match 方法从特定格式的字符串中获取逗号分隔的整数:

'text PaymentID: 12345'.match(PATTERN)[1..-1]          # expected result: ['12345']
'text Payment ID: 12345'.match(PATTERN)[1..-1]         # expected result: ['12345']
'text Payment id 12345'.match(PATTERN)[1..-1]          # expected result: ['12345']
'text paymentid:12345'.match(PATTERN)[1..-1]           # expected result: ['12345']
'text payment id: 12345'.match(PATTERN)[1..-1]         # expected result: ['12345']
'text payment ID: 111,999'.match(PATTERN)[1..-1]       # expected result: ['111', '999']
'text payment ID: 111, 222, 333'.match(PATTERN)[1..-1] # expected result: ['111', '222', '333']

所以所有空格和':'符号都是可选的,模式应该不区分大小写,payment 之前的文本可以包含任何字符。 我的最后一个变种不够好:

PATTERN = /payment[\s]?id[:]?[\s]?(\d+)(?:[,]?[\s]?(\d+))+/i

> 'text Payment id: 12345'.match(PATTERN)[1..-1]
=> ["1234", "5"]
> 'text Payment id: 12345, 333, 91872389'.match(PATTERN)[1..-1]
=> ["12345", "91872389"]

关于如何实现这一目标的任何想法?提前致谢。

【问题讨论】:

为什么不text.scan(/\d+/)?或者text.scan(/(?:\G(?!\A)\s*,|payment\s?id:?)\s*\K\d+/i) @WiktorStribiżew payment 单词之前的文本可以包含任何字符,包括数字。问题已更新,抱歉。我将测试第二个正则表达式,它看起来适合我的需要。 【参考方案1】:

你可以使用

text.scan(/(?:\G(?!\A)\s*,|payment\s?id:?)\s*\K\d+/i)

正则表达式匹配

(?:\G(?!\A)\s*,|payment\s?id:?) - 上一个成功匹配的结尾,然后是零个或多个空格和一个逗号或payment,一个可选的空格,id 和一个可选的冒号 \s* - 零个或多个空格 \K 从比赛中删除刚刚消耗的内容 \d+ - 一位或多位数字。

【讨论】:

【参考方案2】:

您不能重复捕获组,因为最后一次出现将覆盖前一次。您可以做的是使用基于\G 的模式,以确保连续匹配之间的连续性与扫描方法:

PATTERN = /(?:(?!\A)\G\s*,|payment\s*id\s*:?)\s*(\d+)/i

'text Payment id: 12345, 333, 91872389'.scan(PATTERN).flatten

简而言之,第二个分支payment\s*id\s*:? 必须首先成功,以允许第一个分支(?!\A)\G\s* 在接下来的匹配中成功。

【讨论】:

以上是关于通过正则表达式获取逗号分隔的数字的主要内容,如果未能解决你的问题,请参考以下文章

带有逗号分隔符的数字的正则表达式验证

用于验证数字逗号分隔值的 Java 正则表达式

正则表达式 环视 逗号分隔数字

在逗号分隔的字母数字正则表达式中添加空格

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

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