Python正则:交替运算符|后捕获组无法通过re.match()获取
解决re.match中交替运算符|导致捕获组无法正常获取的问题
这问题我之前也踩过坑,本质是正则里交替分支(|)的捕获组编号规则在搞鬼!
为什么原来的代码会返回None?
你写的正则是两个独立分支:
pattern = r"00([1-9]\d) ([1-9]\d) ([1-9]\d{5})|\+([1-9]\d) ([1-9]\d) ([1-9]\d{5})"
正则引擎会按顺序给所有捕获组编号:
- 第一个分支里的三个括号对应组1、组2、组3
- 第二个分支里的三个括号对应组4、组5、组6
当你用"+12 34 567890"测试时,匹配的是第二个分支,这时候组1、组2、组3根本没被匹配到,自然返回None;你要的12其实在组4里,试试print(m.group(4))就能拿到正确结果了。
两种优雅的解决方案
方案1:提取公共前缀,统一捕获组编号
既然两个分支只有前缀(00和+)不同,后面的结构完全一致,我们可以把前缀做成一个非捕获组((?:...)),这样后面的三个捕获组编号就统一为1、2、3了:
import re strng = "+12 34 567890" # 用(?:00|\+)包裹前缀,非捕获组不占用编号 pattern = r"(?:00|\+)([1-9]\d) ([1-9]\d) ([1-9]\d{5})" m = re.match(pattern, strng) print(m.group(1)) # 输出12 print(m.group(2)) # 输出34 print(m.group(3)) # 输出567890
这个方案最简洁,同时兼容两种前缀的匹配,捕获组的使用也和你预期一致。
方案2:使用命名捕获组
如果分支结构差异较大,没法提取公共部分,可以给对应位置的捕获组起相同的名字,这样不管匹配哪个分支,都能通过名字获取值:
import re strng = "+12 34 567890" pattern = r"00(?P<country>[1-9]\d) (?P<area>[1-9]\d) (?P<number>[1-9]\d{5})|\+(?P<country>[1-9]\d) (?P<area>[1-9]\d) (?P<number>[1-9]\d{5})" m = re.match(pattern, strng) print(m.group('country')) # 输出12 print(m.group('area')) # 输出34 print(m.group('number')) # 输出567890
命名组的好处是可读性强,不会因为分支变化导致编号混乱。
测试验证
不管用哪种方案,测试"0012 34 567890"也能正常捕获到对应的三个值,完美解决你的问题~
内容的提问来源于stack exchange,提问作者Elle
相关产品推荐
相关产品推荐

