从YAML加载带转义字符的正则表达式匹配失败,求解决方案
解决YAML加载正则表达式匹配失败的问题
问题原因
核心问题是YAML的字符串转义规则和Python正则的需求不匹配:
- 你在YAML中用单引号包裹正则
'\s*HEADER\d+\n',PyYAML解析时会对字符串中的反斜杠进行转义,最终得到带双反斜杠的字符串(\\s*HEADER\\d+\\n),导致正则引擎把\\s识别成字面量\s而非空白匹配符,自然匹配失败。 - 你尝试添加自定义构造函数但无效,是因为YAML里没给正则标记对应的
!!python/regexp标签,构造函数无法触发。
可行解决方案
方案1:修改YAML字符串写法(推荐)
方式A:双引号转义反斜杠
在YAML中用双引号包裹正则,对每个反斜杠额外转义一次:
regex_sample: "\\s*HEADER\\d+\\n"
YAML解析后会自动把\\转为单个\,最终得到符合正则要求的字符串\s*HEADER\d+\n。
方式B:使用字面量块标量
用YAML的字面量块标量,无需转义任何字符,完全保留原始内容:
regex_sample: | \s*HEADER\d+\n
方案2:加载后用ast.literal_eval还原转义
如果不能修改YAML文件,可在Python中用ast.literal_eval将解析后的字符串还原为正则所需格式:
import yaml import re import ast with open("reg_ents.yaml", 'r', encoding="utf-8") as yaml_instr: new_yaml = yaml.safe_load(yaml_instr) # 通过字面量解析还原转义字符 regex_str = ast.literal_eval(f"'{new_yaml['regex_sample']}'") nregex = re.compile(regex_str, flags=re.I) print(nregex.findall("\nHEADER1\n")) # 输出: ['\nHEADER1\n']
方案3:使用YAML自定义标签(需修改YAML)
给YAML中的正则添加!!python/regexp标签,配合自定义构造函数直接编译为正则对象:
- 修改YAML文件:
regex_sample: !!python/regexp '\s*HEADER\d+\n'
- 修改Python代码:
import yaml import re # 注册自定义构造函数 yaml.SafeLoader.add_constructor( 'tag:yaml.org,2002:python/regexp', lambda loader, node: re.compile(loader.construct_scalar(node), flags=re.I) ) with open("reg_ents.yaml", 'r', encoding="utf-8") as yaml_instr: new_yaml = yaml.safe_load(yaml_instr) nregex = new_yaml['regex_sample'] print(nregex.findall("\nHEADER1\n")) # 输出: ['\nHEADER1\n']
内容的提问来源于stack exchange,提问作者Jon
相关产品推荐
相关产品推荐

