Python正则表达式re.findall匹配结果不符预期的原因咨询
正则表达式findall结果异常的原因分析
核心问题:re.findall的捕获组优先级
Python的re.findall()有个关键特性:当正则表达式中包含捕获组时,它会优先返回捕获组匹配的内容,而非整个正则匹配的完整字符串;如果捕获组处于重复匹配结构(比如*、+)中,会返回该捕获组最后一次匹配的内容。
第一个案例解析
代码:
import re a_re = r"`(``|[^`])*`" a_str = '`abc`12`cde`45' b = re.findall(a_re,a_str) print(b) # ['c', 'e']
分析:
- 正则
r"(``|[^])*"`的结构:- 以
开头,以结尾 - 中间的
(``|[^])*是重复匹配:要么匹配两个连续的,要么匹配非`的任意字符,重复0次或多次
- 以
- 匹配过程:
- 第一个匹配块是
abc:捕获组依次匹配a、b、c,最后一次捕获的是c - 第二个匹配块是
cde:捕获组依次匹配c、d、e,最后一次捕获的是e
- 第一个匹配块是
findall()收集每个匹配块中捕获组的最后一次匹配结果,所以输出['c', 'e']
第二个案例解析
代码:
import re a_re = r"`(ab|[^c])*`" a_str = '`ab`1`df`' b = re.findall(a_re,a_str) print(b) # ['f']
分析:
- 正则
r"(ab|[^c])*"的结构:- 以
开头,以结尾 - 中间的
(ab|[^c])*是重复匹配:要么匹配ab,要么匹配非c的任意字符,重复0次或多次
- 以
- 匹配过程:
- 第一个候选匹配块
ab:正则的贪婪特性会尝试继续匹配后续字符——后面的属于非c字符,会被[^c]匹配,导致整个正则的结尾无法匹配,触发回溯后最终放弃匹配这个ab块 - 第二个匹配块
df:捕获组依次匹配d、f,最后一次捕获的是f
- 第一个候选匹配块
- 因此
findall()只收集到第二个匹配块的捕获结果,输出['f']
解决建议
如果想获取整个匹配的字符串而非捕获组内容,有两种方式:
- 把捕获组改为非捕获组:在组开头加
?:,比如r"(?:``|[^])*"` - 使用
re.finditer()遍历匹配对象,通过.group()获取完整匹配内容
内容的提问来源于stack exchange,提问作者巴萨说
相关产品推荐
相关产品推荐

