You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为什么正则(\d)\d\1无法匹配交替重复数字?Python re.findall仅返回5

原有正则不符合预期的核心原因

你碰到的返回结果偏差,是Python re模块两个基础机制共同导致的:

  • re.findall的返回规则:当正则存在捕获组时,函数默认返回每个匹配对应的捕获组内容列表,而非完整的匹配字符串。你写的(\d)\d\1只设置了1个捕获组,就算成功命中完整的525三字符片段,也只会返回捕获组记录的单个数字,不会返回片段中间的字符、以及和第一个数字同值的尾部字符。
  • 非重叠匹配的默认逻辑:Python re模块扫描字符串时,每完成一次匹配,下一次的扫描起点会直接跳到本次匹配的结束位置之后,不会主动查找和已匹配片段重叠的内容。对应你的示例字符串552523,扫描过程为:

    从头开始寻找符合(\d)\d\1的片段时,第一个命中的是索引1到3位置的525(字符为位置1的5、位置2的2、位置3的5),匹配结束在位置3,下一次扫描直接从位置4开始;而位于索引2到4位置的252片段,因为和上一次的匹配共享了位置3的字符,属于重叠内容,直接被跳过。

这也是你运行代码后只返回单个5、没有拿到后续2的根本原因。

实现目标需求的可行方法

要拿到示例中(5,5)、(2,2)的数字配对,只需要对正则逻辑做两处调整:

  • 把需要提取的两个相同数字都设置为独立捕获组,方便findall直接返回配对内容,替代原来单捕获组的写法。
  • 用零宽正向前瞻结构实现重叠位置的扫描,避免因为非重叠匹配漏掉跨位置的符合规则的片段。

调整后的正则表达式为:(?=(\d)\d(\1))
这个正则的逻辑是:从字符串的每个位置开始,向后窥探3个字符的长度,不实际消耗当前扫描位置的字符(零宽特性),只要发现第一个和第三个字符是相同数字(符合ABA的交替重复结构),就把这两个相同数字作为捕获组内容记录下来。

对应示例的实际运行效果:

示例代码:re.findall(r'(?=(\d)\d(\1))', '552523')
运行返回:[('5', '5'), ('2', '2')]

如果需要得到整数类型的配对,只要把返回结果里的字符串元素转换为对应整数即可。


内容的提问来源于stack exchange,提问作者Sasi Kanth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.29 16:36:03