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

2024-04-19 20:05:24 发布

您现在位置:Python中文网/ 问答频道 /正文

在下面的代码片段中,匹配结果中应忽略非捕获组"(?:aaa)"

结果应仅为"_bbb"

然而,我在匹配结果中得到"aaa_bbb";只有当我指定组(2)时,它才会显示"_bbb"

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

aaa_bbb

Tags: 代码importrematchgroupprintbbbaaa
3条回答

TFM

class re.MatchObject

group([group1, ...])

返回匹配的一个或多个子组。如果有一个参数,则结果是一个字符串;如果有多个参数,则结果是一个元组,每个参数有一个项。如果没有参数,group1默认为零(返回整个匹配项)。如果groupN参数为零,则相应的返回值是整个匹配字符串。

我认为你误解了“非抓捕组”的概念。由非捕获组匹配的文本仍然成为整个regex匹配的一部分。

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

非捕获组的主要好处是,您可以将它们添加到regex中,而不会影响regex中捕获组的编号。它们还提供(稍微)更好的性能,因为regex引擎不必跟踪由非捕获组匹配的文本。

如果您真的想从整个regex匹配中排除aaa,那么您需要使用lookaround。在这种情况下,正后面看可以实现以下技巧:(?<=aaa)_bbb。使用这个regex,group()在Python中返回_bbb。不需要捕获组。

我的建议是,如果您能够使用捕获组来获取部分正则表达式匹配,请使用该方法而不是四处查看。

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

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

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

相关问题 更多 >