繁体   English   中英

正则表达式由于重复捕获组而不是匹配重复组而不匹配

[英]regex not matching due to repeated capturing group rather than capturing a repeated group

我有以下正则表达式:

/(?:[\[\{]*)(?:([A-G\-][^A-G\]\}]*)+)(?:[\]\}]*)/

具有以下表达式:

{A''BsCb}

我希望有3个匹配结果

A''
Bs
Cb

但是在https://regex101.com/上进行的测试仅给我最后一次匹配Cb ,并告诉我重复捕获组将仅捕获最后一次迭代,将捕获组放在重复组周围。

我以为那是我所做的! 我以为我已经理解了这里描述的问题http://www.regular-expressions.info/captureall.html因此,在+括号内是捕获组。

但是,要么为时已晚,要么我需要一个不冒头的人来提及regexp来告诉我我哪里出问题了。

您可以通过preg_match_all在项目0处以这种模式获得它:

~
(?:
    \G (?!\A) # contiguous to previous match, but not at the start of the string
  |
    { (?=[^}]* }) # start with { and check if a closing bracket follows 
  |
    \[ (?=[^]]* ]) # the same for square bracket
)
\K # start the match result here
[A-G] [^]A-G}]* 
~xS

演示

您正在尝试匹配重复的捕获组并获取捕获。 PHP PCRE正则表达式是不可能的。

您可以做的是确保提取所有{...} / [...]子字符串,从括号中修剪掉它们,并使用简单的[AG-][^AG]*正则表达式,或添加\\G运算符,使您的正则表达式无法维护,但可以作为原始正则表达式工作。

解决方案1是

/(?:[[{]*|(?!\A)\G)\K[A-G-][^A-G\]}]*/

参见regex演示 注意:此正则表达式不检查结尾的]} ,但可以使用正向提前添加。

  • (?:[[{]*|(?!\\A)\\G) -匹配[{ ,出现零个或多个,或上一次成功匹配的结束位置
  • \\K省略到目前为止匹配的文本
  • [AG-] G - [AG-] -从AG字母和-
  • [^AG\\]}]* -零个或多个从AG以及[ ]}以外的字符。

参见PHP演示

解决方案2是

$re = '/(?|{([^}]*)}|\[([^]]*)])/'; 
$str = "{A''BsCb}"; 
$res = array();
preg_match_all($re, $str, $m);
foreach ($m[1] as $match) {
    preg_match_all('~[A-G-][^A-G]*~', $match, $tmp);
    $res = array_merge($tmp, $res);
}
print_r($res);

参见PHP演示

(?|{([^}]*)}|\\[([^]]*)])正则表达式仅匹配{...}[...]类的字符串(但不匹配{...][...} )并将括号之间的内容捕获到组1中(因为分支重置组(?|...)重置了每个分支中的组ID)。 然后,我们所需要的只是使用更连贯的'~[AG-][^AG]*~'正则表达式来获取我们所需要的东西。

您已经知道了。 关于@sln的评论,当在PCRE中重复一个PHP的正则表达式风格的组时,没有办法在一个或不同的捕获组中收集每个单个匹配项。 在这种情况下,仅捕获最后一个匹配项。

但是,如果断言在字符串的开头和结尾处都应有括号,则不重要,而您只需要这些值,那么要做的工作就更少了:

$array = array_filter(preg_split("~(?=[A-G])~", trim("{A''BsCb}", '[{}]')));

正则表达式:

(?=[A-G]) # Positive lookahead to find next character be one from character class

此正则表达式将匹配所有相似的位置以在拆分时输出正确的数据:

array(3) {
  [1]=>
  string(3) "A''"
  [2]=>
  string(2) "Bs"
  [3]=>
  string(2) "Cb"
}

现场演示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM