【问题标题】:Python Regex Findall non-greedyPython 正则表达式 Findall 非贪婪
【发布时间】:2026-01-16 06:35:01
【问题描述】:

我对正则表达式比较陌生,我似乎很难理解贪婪与非贪婪搜索(如果这确实是这里的问题)。假设我有这样一个简单的文本:

# 数字:4 A 3 B

我的目标是运行 findall 以获得类似以下输出:

['# number:', '4 A 3 B', '4 A', '3 B']

因此,如果我将以下正则表达式与 findall 一起使用,我希望它可以工作:

matches = re.findall(r"(# numbers:)(((?:\s\d)(?:\s\D))*)", "# numbers: 4 A 3 B")

然而,实际的输出是这样的:

[('#个数字:', '4 A 3 B', '3 B')]

有人可以解释为什么组 ((\s\d)(\d\D)) 只匹配“3 B”而不匹配“4 A”吗?我认为这与 * 的贪婪与非贪婪搜索有关,这是真的吗?如果是这样,您能解释一下如何解决这个问题吗?

提前致谢!

【问题讨论】:

    标签: python regex findall


    【解决方案1】:

    我会在这里使用re.findall,两次。首先,提取数字/非数字文本系列,然后再次使用re.findall 查找元组:

    inp = "# numbers: 4 A 3 B"
    text = re.findall(r'^# numbers:\s+(.*)$', inp)[0]
    matches = re.findall(r'(\d+)\s+(\D+)', text)
    print(matches)  # [('4', 'A '), ('3', 'B')]
    

    【讨论】:

    • 感谢您的想法!我也想过这个问题,但我想知道为什么第一个解决方案不起作用。如果在“findall”中找到任何组,我会假设任何组都被搜索并返回。为什么只有最后一个,你知道吗?
    • 你使用了:(((?:\s\d)(?:\s\D))*) ...这会将整个重复模式放入一个捕获组中,Python 的正则表达式引擎只会“记住”最后一个匹配项。
    • 我明白了,您知道是否无法在每次找到重复模式时都“记住”它?
    • 您当前的方法无法挽救 AFAIK,因此我的解决方法是。
    • 感谢您的输入,但我仍然不明白为什么 re.findall(r'(\d+)\s+(\D+)', text) 找到所有模式,但 re.findall (r'(\d+)\s+(\D+)*', text) (with ) 没有。 re.findall(r'(\d+)\s+(\D+)?', text) (with *?) 似乎也可以正常工作。奇怪