为什么正则表达式的"非捕获"组不起作用

Jim*_*rng 44 python regex

在下面的代码片段中,匹配结果中应忽略非捕获组"(?:aaa)",因此结果应该"_bbb"只是.

但是,我得到"aaa_bbb"了匹配的结果; 只有当我指定组(2)时才会显示"_bbb".

>>> import re
>>> s = "aaa_bbb"
>>> print(re.match(r"(?:aaa)(_bbb)", s).group())

aaa_bbb
Run Code Online (Sandbox Code Playgroud)

Jan*_*rts 84

我认为你误解了"非捕获群体"的概念.由非捕获组匹配的文本仍然成为整个正则表达式匹配的一部分.

正则表达式(?:aaa)(_bbb)和正则表达式都(aaa)(_bbb)返回aaa_bbb整体匹配.区别在于第一个正则表达式有一个捕获组_bbb作为匹配返回,而第二个正则表达式有两个捕获组返回aaa_bbb作为它们各自的匹配.在你的Python代码中,_bbb你需要使用group(1)第一个正则表达式和group(2)第二个正则表达式.

非捕获组的主要好处是您可以将它们添加到正则表达式而不会破坏正则表达式中捕获组的编号.它们还提供(稍微)更好的性能,因为正则表达式引擎不必跟踪非捕获组匹配的文本.

如果您真的想aaa从整体正则表达式匹配中排除,那么您需要使用环视.在这种情况下,积极的外观可以解决问题:(?<=aaa)_bbb.有了这个正则表达式,group()返回_bbbPython.不需要捕获组.

我的建议是,如果您能够使用捕获组来获取正则表达式匹配的一部分,请使用该方法而不是环视.

  • 这是一个比接受的答案更有用的答案. (10认同)

Ric*_*ões 42

group()并且group(0)将返回整场比赛.后续组是实际的捕获组.

>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(0))
aaa_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(1))
_bbb
>>> print (re.match(r"(?:aaa)(_bbb)", string1).group(2))
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: no such group
Run Code Online (Sandbox Code Playgroud)

如果你想要相同的行为group():

" ".join(re.match(r"(?:aaa)(_bbb)", string1).groups())