翻译过滤器外部字典:如何在YAML中存储正则表达式?CSV/JSON是否更优?
刚好我之前处理过类似的正则存储问题,先帮你解决当前YAML示例里的核心问题——单引号嵌套的语法错误。YAML里如果字符串本身包含单引号,必须把内部的单引号写成两个连续的单引号才能正确解析,不然会触发语法异常。另外,对于包含^、$、[]这类正则特殊字符,或者:、-这类YAML结构符号的正则,最好用单引号或双引号把整个正则包裹起来,避免YAML把它们当成语法元素误解析。
修正后的YAML示例应该是这样的:
'Rejected': onewordstatus '^Send to some module': twoword status '^Image converted': twoword status 'Something': two wordstatus 'Error - input Source = ''F'' or ''E''': status2 # 内部单引号转义为两个连续单引号 '^[a-z;A-Z]* Module Done$': status3
如果你的正则里有双引号,也可以用双引号包裹整个字符串,内部双引号用\转义,比如:
"Error - input Source = \"F\" or \"E\"": status2
我帮你对比三种格式的优缺点,你可以根据自己的使用场景选择:
不推荐CSV的原因
CSV的结构过于简单,遇到正则里的逗号、引号、换行符时,转义规则会变得极其繁琐,很容易出现解析错误。比如你那个带单引号的正则,在CSV里要处理成"Error - input Source = 'F' or 'E'",status2,如果正则本身包含双引号,还要额外转义,可读性和维护性都很差——除非你的正则极其简单,否则完全不建议用CSV。
JSON:兼容性拉满的选择
JSON的语法非常严格,字符串转义规则明确,所有正则都可以用双引号包裹,内部的双引号用\转义即可,比如:
{ "Rejected": "onewordstatus", "^Send to some module": "twoword status", "Error - input Source = \"F\" or \"E\"": "status2", "^[a-z;A-Z]* Module Done$": "status3" }
几乎所有编程语言都有成熟的JSON解析库,跨语言使用毫无压力,而且不容易出现解析歧义。唯一的小缺点就是写法比YAML啰嗦,多了不少大括号和引号。
YAML:可读性最优的选择
如果你的团队主要是人类来编辑维护这个映射文件,YAML绝对是首选——它的语法简洁,看起来更像自然语言,不需要额外的大括号和逗号(除了键值对的冒号)。只要你掌握了单引号/双引号的转义规则,存储正则完全没问题,就像我上面给的修正示例那样。唯一要注意的是,不同YAML解析器对某些边缘情况的处理可能略有差异,但主流解析器(比如PyYAML、Ruby YAML)的表现都是一致的。
总结一下:如果追求跨语言兼容性和解析可靠性,选JSON;如果追求易读易编辑,选YAML;尽量避开CSV。
内容的提问来源于stack exchange,提问作者Piotr Perak

