【问题标题】:Why doesn't this regex capture group repeat for each match?为什么这个正则表达式捕获组不为每场比赛重复?
【发布时间】:2015-12-24 23:42:18
【问题描述】:

我正在 regex101.com 上测试这个

正则表达式:^\+([0-9A-Za-z-]+)(?:\.([0-9A-Za-z-]+))*$

测试字符串:+beta-bar.baz-bz.fd.zz

字符串匹配,但“匹配信息”框显示只有两个捕获组:

MATCH 1 1. [1-9] `beta-bar` 2. [20-22] `zz`

我期待所有这些捕获:

  1. 测试栏
  2. baz-bz
  3. fd
  4. zz

为什么期间之间的每个标识符都没有被识别为自己的捕获组?

【问题讨论】:

  • 解释很简单:因为你使用了*量词,所以只有捕获组的最后一次重复存储在缓冲区中。您可以使用[+.] 模式拆分字符串。
  • 如果要将捕获的匹配分为四组,则需要将模式写出以匹配整个字符串,即^\+([^.]+)\.([^.]+)\.([^.]+)\.([^.]+)$
  • 捕获组是静态确定的:正则表达式中的第一个( 开始第1 组,第二个( 开始第2 组,等等。
  • 谢谢大家。可以有 n 个组,所以我不能对其进行硬编码。我猜正则表达式在自动捕获每个标识符的同时无法表达(和捕获)完整的 semver-spec。 :(
  • stribizhev 的回答是正确的,但值得一提的是,.net 实际上返回了与捕获组匹配的所有捕获的集合。请参阅Group.Captures 属性:msdn.microsoft.com/en-us/library/… ... 请添加您的编程语言的标签,因为了解正则表达式的风格很重要

标签: regex


【解决方案1】:

发生这种情况的原因是,当在捕获组上使用量词并捕获 n 次时,只有最后捕获的文本会存储在缓冲区中并在最后返回。

您可以使用简单的正则表达式[+.] preg_split 来匹配您拥有的字符串,而不是匹配这些部分:

$str = "+beta-bar.baz-bz.fd.zz";
$a = preg_split('/[+.]/', $str, -1, PREG_SPLIT_NO_EMPTY);

IDEONE demo

结果:

Array
(
    [0] => beta-bar
    [1] => baz-bz
    [2] => fd
    [3] => zz
)

【讨论】:

  • 我刚刚意识到我假设您使用的是 PHP。如果 t 是,请将标签添加到问题中。
猜你喜欢
  • 1970-01-01
  • 2013-08-13
  • 2016-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-04
相关资源
最近更新 更多