【问题标题】:Regex to match a digit two or four times正则表达式匹配一个数字两次或四次
【发布时间】:2011-11-18 02:43:35
【问题描述】:

这是一个关于正则表达式的简单问题,但我没有找到答案。

我想确定一个数字是否恰好按顺序出现两次四次次。我可以使用什么语法?

\d{what goes here?}

我试过\d{2,4},但这个表达式也接受三个数字。

【问题讨论】:

  • 例如,匹配两位或四位的年份
  • 如果字符串是abc 123 xyz,你想发生什么?它是否应该匹配12,因为这恰好是两个数字?还是不应该,因为12 是更大数字序列123 的一部分,它本身既不是2 也不是4 长?如果我不得不猜测,我认为你想要后一种行为,但你的问题并不清楚。示例和/或更清晰的规范会有所帮助。 abc 12345 def 的同样问题...那里应该发生什么?

标签: regex numbers


【解决方案1】:

没有具体的语法,但有很多方法可以做到:

(?:\d{4}|\d{2})    <-- alternation: four digits if possible, else just two
\d{2}(?:\d{2})?    <-- two digits, plus two more if possible
(?:\d{2}){1,2}     <-- two digits, times one or two

因此,例如,要匹配由一个或多个字母 A–Z 后跟两位或四位数字组成的字符串,您可以编写 ^[A-Z]+(?:\d{4}|\d{2})$;要匹配逗号分隔的两位或四位数字列表,您可以编写 ^((?:\d{4},|\d{2},)*(?:\d{4}|\d{2})$^(?:\d{2}(?:\d{2})?,)*\d{2}(?:\d{2})$

【讨论】:

  • 就我个人而言,只是一开始就想到了\d{2}(?:\d{2})? 解决方案——其中种类繁多——尤其是最后一个,看起来非常好且可扩展。
  • +1 表示在使用交替匹配首先匹配 4 位数字时需要注意的顺序,然后是 2 位数字。提供其他变体也很好。
  • 对于像我一样不理解(?: 用法的任何人,这将启动一个“非捕获组”(一个不打算在替换语句中引用的组)。您也可以只使用括号,但这些将创建一个捕获组。更多细节在这里:stackoverflow.com/questions/3512471/non-capturing-group
  • 这些将显示“333”和“33”的相同结果
  • @Dan:这些正则表达式匹配完整的字符串"333"。您可能错误地使用了正则表达式库的“查找匹配的子字符串”功能,而不是“检查是否完整的字符串匹配”功能。您应该查阅其文档。
【解决方案2】:
(?<!\d)(\d{2}|\d{4})(?!\d)

这是正确的做法。接受的答案是错误的。

它将匹配 3 个数字(或 5 个)。 So that is wrong in my eyes.

1) 检查在 2 位或 4 位数字序列之前,或在 2 位或 4 位数字序列之后没有数字。

  • (&lt;!) 语法为负向回溯

  • (?!) 语法为负前瞻。

以上内容适用于中间字符串:

如果您的搜索字符串周围没有内容,您可以使用^$ 字符串锚点的开始和结束:

^\d{4}$|^\d{2}$

【讨论】:

  • 我不会说accepted answer 是错误的。我会说 question 不清楚,并且该答案解决了对它的一种有效解释。您的回答解决了另一种有效的解释(我碰巧认为它更有可能 - 但显然提问者没有......)。
  • “它将匹配 3 位数字”不太准确。我认为您的意思是“它将匹配 3 位序列的 2 位子序列。”
  • 另外,你的答案doesn't quite work as intended on sequences of 5 or more digits。我不是正则表达式专家,但我想fix it 的一种方法是使负前瞻/后向适用于两种情况(2 位和 4 位序列):(?&lt;!\d)(\d{2}|\d{4})(?!\d)
  • 我认为你对 5 位数字是正确的。感谢您的更正。会解决的。
  • ^\d{4}$|^\d{2}$ 将是解决此问题的潜在方法。 ^\d{2}(?!\d)|^\d{4}(?!\d) 也一样
猜你喜欢
  • 2020-06-23
  • 1970-01-01
  • 1970-01-01
  • 2012-01-28
  • 1970-01-01
  • 2015-04-27
  • 2022-01-11
  • 1970-01-01
  • 2015-11-14
相关资源
最近更新 更多