Python2.7中re.sub报'unmatched group'错误,求列表转字典方案修正
正则表达式在Python2.7中抛出"unmatched group"错误的原因及修复
问题背景
有如下字符串列表,每个元素是空格分隔的键值对:
listA = [ 'abcd1-2 4d4e', 'xyz0-1 551', 'foo 3ea', 'bar1 2bd', 'mc-mqisd0-2 77a' ]
需求是将其转换为字典,其中带数字范围的键(如xyz0-1)需要展开为多个键(如abcd1、abcd2)并对应相同值,预期结果如下:
{ 'abcd1': '4d4e', 'abcd2': '4d4e', 'xyz0': '551', 'xyz1': '551', 'foo': '3ea', 'bar1': '2bd', 'mc-mqisd0': '77a', 'mc-mqisd1': '77a', 'mc-mqisd2': '77a', }
编写的Python3兼容函数如下,但在Python2.7环境(Ansible插件)中执行时抛出unmatched group错误:
def listFln(listA): import re fL = [] for i in listA: aL = i.split()[0] bL = i.split()[1] comp = re.sub('^(.+?)(\d+-\d+)?$',r'\1',aL) cmpCountR = re.sub('^(.+?)(\d+-\d+)?$',r'\2',aL) if cmpCountR.strip(): nStart = int(cmpCountR.split('-')[0]) nEnd = int(cmpCountR.split('-')[1]) for j in range(nStart,nEnd+1): fL.append(comp + str(j) + ' ' + bL) else: fL.append(i) return(dict([k.split() for k in fL]))
错误信息:
cmpCountR = re.sub('^(.+?)(\d+-\d+)?$',r'\2',aL) File "/usr/lib64/python2.7/re.py", line 151, in sub return _compile(pattern, flags).sub(repl, string, count) File "/usr/lib64/python2.7/re.py", line 275, in filter return sre_parse.expand_template(template, match) File "/usr/lib64/python2.7/sre_parse.py", line 800, in expand_template raise error, "unmatched group"
错误原因
问题出在正则表达式的可选捕获组处理差异上:
- 正则
^(.+?)(\d+-\d+)?$中的第二个组(\d+-\d+)?是可选的(末尾的?表示匹配0次或1次)。 - 当处理不带数字范围的键(如
foo、bar1)时,第二个组完全没有匹配到。 - Python3中,
re.sub会将未匹配的捕获组引用(如\2)替换为空字符串;但Python2.7的re模块不允许引用未匹配的捕获组,直接抛出"unmatched group"错误。
修复方案
改用re.match获取匹配对象,通过group()方法安全获取捕获组内容,未匹配的组返回None,再手动替换为空字符串即可。修正后的兼容Python2.7的函数如下:
def listFln(listA): import re # 提前编译正则,提升循环内执行效率 pattern = re.compile(r'^(.+?)(\d+-\d+)?$') fL = [] for i in listA: # 直接拆分键值对,简化赋值 aL, bL = i.split() match = pattern.match(aL) comp = match.group(1) # 未匹配到第二个组时,用空字符串替代None cmpCountR = match.group(2) or '' if cmpCountR.strip(): # 一次性转换起始/结束数字 nStart, nEnd = map(int, cmpCountR.split('-')) for j in range(nStart, nEnd + 1): fL.append(comp + str(j) + ' ' + bL) else: fL.append(i) # 生成最终字典 return dict(k.split() for k in fL)
内容的提问来源于stack exchange,提问作者Vijesh
相关产品推荐
相关产品推荐

