Python正则规则字典如何实现链式引用的递归替换功能
问题原因分析
- 原代码核心逻辑错误:所有占位符替换时固定取字典第一个条目的值替换,没有匹配占位符对应的键名,导致所有
#xxx#格式的内容都被替换为字典第一个元素的值 - 无多层引用处理逻辑:单次替换仅能处理一层引用,无法处理链式嵌套的多层引用场景
修复后代码
import re def expand_re(pat_dict: dict[str, str]): # 编译匹配占位符的正则,捕获占位符对应的键名 placeholder_pattern = re.compile(r'#(\w+)#') # 循环替换直到没有占位符为止,处理链式引用 while True: has_update = False for key, rule in pat_dict.items(): def replace_match(match): nonlocal has_update ref_key = match.group(1) has_update = True return f"(?:{pat_dict[ref_key]})" # 替换当前规则里的所有占位符 new_rule = placeholder_pattern.sub(replace_match, rule) if new_rule != rule: pat_dict[key] = new_rule # 本轮没有任何更新说明所有占位符都替换完成,退出循环 if not has_update: break return pat_dict
测试效果
单层引用场景测试
输入:
pd = dict(digit = r'[0-9]', integer = r'[+-]?#digit##digit#*') print(expand_re(pd))
输出:{'digit': '[0-9]', 'integer': '[+-]?(?:[0-9])(?:[0-9])*'},和预期效果一致。
链式引用场景测试
输入:
pd = dict(a='correct',b='#a#',c='#b#',d='#c#',e='#d#',f='#e#',g='#f#') print(expand_re(pd))
输出:
{ 'a': 'correct', 'b': '(?:correct)', 'c': '(?:(?:correct))', 'd': '(?:(?:(?:correct)))', 'e': '(?:(?:(?:(?:correct))))', 'f': '(?:(?:(?:(?:(?:correct)))))', 'g': '(?:(?:(?:(?:(?:(?:correct))))))' }
完全符合逐层嵌套的预期效果。
注意事项
- 请确保引用链没有循环依赖(比如
a='#b#', b='#a#'),否则会进入死循环 - 如果不需要给每个引用都套
(?:)非捕获分组,直接修改替换返回的格式即可
内容的提问来源于stack exchange,提问作者newbiecoder11
相关产品推荐
相关产品推荐

