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

时间:2010-04-24 02:48:15

标签: python regex

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

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

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

aaa_bbb

6 个答案:

答案 0 :(得分:77)

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

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

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

如果您确实要从整体正则表达式匹配中排除aaa,则需要使用lookaround。在这种情况下,正面的后视可以解决问题:(?<=aaa)_bbb。使用此正则表达式,group()在Python中返回_bbb。不需要捕获组。

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

答案 1 :(得分:36)

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())

答案 2 :(得分:2)

TFM

class re.MatchObject

group([group1, ...])

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

答案 3 :(得分:1)

尝试:

print(re.match(r"(?:aaa)(_bbb)", string1).group(1))

group()group(0)相同,群组0始终存在且整个RE 匹配。

答案 4 :(得分:0)

您必须指定group(1)才能获得括号捕获的部分(在本例中为_bbb)。

没有参数的

group()将返回整个字符串匹配的完整正则表达式,无论它的某些部分是否被括号另外捕获。

答案 5 :(得分:0)

在匹配对象上使用groups方法而不是group。它返回所有捕获缓冲区的列表。没有参数的group方法返回正则表达式的整个匹配。