正则表达式匹配分隔字符串两侧共现数字时仅返回首个匹配值的问题咨询
正则表达式匹配分隔字符串两侧共现数字时仅返回首个匹配值的问题咨询
嘿,我来帮你理清这个问题~
首先看你遇到的情况:用re.findall(r'(\d).*%.*\1', '3425%4368')只返回了['3'],却没拿到4,这是因为你的正则匹配逻辑和re.findall的工作机制共同导致的:
你的正则表达式(\d).*%.*\1的匹配过程是这样的:
- 从字符串开头开始,
(\d)首先匹配到第一个数字3 - 接着
.*%会贪婪地匹配从3后面到%的所有内容,也就是425% - 然后
.*\1匹配%后面直到出现3的部分,也就是43 - 这时候整个匹配的子串是
3425%43,re.findall会提取分组里的3,并且因为整个字符串已经被匹配过大部分内容,没有剩余的可匹配区间了,所以不会再去检查4的情况
那怎么拿到同时出现在%两侧的所有数字呢?这里有两种更靠谱的方法:
方法一:拆分字符串后找交集(更直观易读)
先把字符串按%拆成两部分,然后遍历第一部分的每个数字,检查是否存在于第二部分中:
s = '3425%4368' part1, part2 = s.split('%') common_digits = [digit for digit in part1 if digit in part2] print(common_digits) # 输出 ['3', '4']
方法二:用正向预查的正则实现
如果一定要用正则,可以借助正向预查来逐个检查每个数字是否在%后面出现:
import re s = '3425%4368' result = re.findall(r'(\d)(?=.*%.*\1)', s) print(result) # 输出 ['3', '4']
这个正则的逻辑是:
(\d)捕获一个数字(?=.*%.*\1)是正向预断言,它会检查当前数字在%之后的部分是否存在,但不会消耗字符串内容,这样正则就能逐个遍历第一部分的每个数字,符合条件的都会被捕获
备注:内容来源于stack exchange,提问作者chariots of fire




