为什么我无法在Python中匹配正则表达式的最后一部分?

3
我希望能够匹配一个包含可选结尾 'other (\\w+)' 的句子。例如,正则表达式应该匹配以下两个句子,并提取单词 'things':
  • The apple and other things.
  • The apple is big.
我编写了下面的正则表达式。但是,我得到了一个结果为 (None,) 的结果。如果我删除最后一个 ?。我会得到正确的答案。为什么?
>>> re.search('\w+(?: other (\\w+))?', 'A and other things').groups()
(None,)
>>> re.search('\w+(?: other (\\w+))', 'A and other things').groups()
('things',)

因为在使用“?”之后,你预计会有更多的单词跟在“things”后面。 - tanjir
? 导致生成的正则表达式匹配前一个正则表达式的0或1次重复。(来自Python官方网站) - Kenly
2个回答

2

如果您使用:

re.search(r'\w+(?: other (\w+))?', 'A and other things').group()

你将会看到正在发生的事情。由于\w+后面的任何内容都是可选项,所以你的search匹配第一个单词A
根据官方文档

.groups()

返回包含匹配中所有子组(从1到模式中存在的所有组)的元组。

你的search调用没有返回任何子组,因此你得到了:
re.search(r'\w+(?: other (\w+))?', 'A and other things').groups()
(None,)

为了解决您的问题,您可以使用基于替换的正则表达式:
r'\w+(?: other (\w+)|$)'

示例:

>>> re.search(r'\w+(?: other (\w+)|$)', 'A and other things').group()
'and'
>>> re.search(r'\w+(?: other (\w+)|$)', 'The apple is big').group()
'big'

1
正则表达式搜索的规则是它们产生最左侧最长的匹配。是的,如果可能的话,它会尝试给你更长的匹配,但最重要的是,当它找到第一个成功的匹配时,它会停止继续查找。
在第一个正则表达式中,\\w+ 匹配的最左侧点是 A。可选部分在那里不匹配,所以完成了。
在第二个正则表达式中,括号表达式是强制性的,所以 A 不匹配。因此,它继续查找。 \\w+ 匹配了 and,然后第二个 \\w+ 匹配了 things
注意,在Python中使用正则表达式时,特别是那些包含反斜杠的表达式,最好使用r'原始字符串'进行编写。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接