理解Python中的(\D\d)+正则表达式模式

3

我正在花一些时间来理解Python 3中的正则表达式术语,但我无法弄清楚这里的(\D\d)+是如何工作的。

我知道\D表示非数字字符,\d表示数字字符,加号+表示前面的表达式重复一次或多次。但是当我尝试以下代码时,我就无法理解结果。

输入:

import re
text = "a1 b2 c3 d4e5f6"
regex = re.findall(r'(\D\d)+',text)
print(regex)

输出:

['a1', 'b2', 'c3', 'f6']

由于正则表达式中包含加号符号,那么它不应该也输出d4e5f6吗?因为它们是非数字和数字字符的序列。

3
这是"捕获重复组和重复捕获组的区别",您可以通过使组不被捕获来匹配"d4e5f6": (?:\D\d)+。详细解释请参考链接。 - hoyland
1
https://regex101.com/r/O2qyGg/1 - G_M
提供的链接非常有用。非常感谢! - Rodrigo Caetano
1个回答

1
你没有直接重复 \D\d 子模式,而是重复了一个包含该子模式的捕获组(由括号表示)。最终匹配确实是文本 d4e5f6,但它作为三个捕获组的实例来完成,每个捕获组都会覆盖上一个。而 Python 的 re.findall() 在存在捕获组的情况下的行为是返回它们(如果有多个,则返回元组),而不是整体匹配。
Python 3.x 中有一个新的实验性 regex 模块,可以返回单个捕获组的多个匹配项,尽管我不确定它如何与 findall() 交互。你也可以将表达式写成 (?:\D\d)+ - (?: 开始一个非捕获组,因此 findall() 将按预期给出整个匹配项。

你能再解释一下这句话“它将作为三个捕获组的实例,每个实例都会覆盖上一个”吗?我觉得我有点听不懂了。(a1) (b2) (c3) d4e5(f6) - Jongware
d4 匹配捕获组,然后 e5 匹配捕获组(替换先前捕获的文本),然后 f6 匹配(再次替换之前的)。最终只有 f6 被捕获,即使所有六个字符都匹配。 - jasonharper
@jasonharper 我想你指的是与正则表达式模块重叠吗?我尝试使用 regex.findall(r'(\D\d)+',text, overlapped=True),结果最后3个元素是 f6 - Sundeep

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