使用pyparsing实现Shell风格变量插值,转义$不生效问题求助
Shell风格字符串变量插值的PyParsing修复方案
你的问题出在负前瞻的使用方式上:~pp.Literal("\\")只是检查当前匹配起始位置是否是反斜杠,但当解析器遇到\$foo时,它会从$的位置开始匹配——此时起始位置是$,负前瞻条件成立,导致$foo被错误替换,最终得到\bar。
要解决这个问题,需要检查$的前一个字符是否为反斜杠,同时单独处理转义后的\$(避免被拆分解析)。以下是修正后的代码:
import pyparsing as pp vars = {"foo": "bar"} # 匹配转义的\$,直接保留原字符串 escaped_dollar = pp.Literal(r"\$").set_parse_action(lambda t: t[0]) # 匹配未被转义的$var:确保$前没有反斜杠,替换为对应变量值 var_ref = ( ~pp.PrecededBy(pp.Literal("\\")) + pp.Literal("$").suppress() + pp.common.identifier ).set_parse_action(lambda t: vars[t[0]]) # 组合所有模式:处理转义$、变量引用,其余普通字符直接保留 interp = pp.ZeroOrMore(escaped_dollar | var_ref | pp.Word(pp.printables, exclude_chars="$\\") | pp.White()) print(interp.transform_string("x $foo x")) print(interp.transform_string("x \\$foo x"))
代码说明
escaped_dollar:专门匹配\$,解析时直接返回原字符串,保证转义后的$不被替换。var_ref:~pp.PrecededBy(pp.Literal("\\")):用负前置检查确保$的前一个字符不是反斜杠;- 匹配
$并忽略它,接着匹配标识符,最后通过parse_action替换为变量值。
interp:用ZeroOrMore遍历整个字符串,依次处理转义$、变量引用,剩下的普通字符(包括非$、非\的可打印字符和空白)直接保留。
输出结果
x bar x x \$foo x
内容的提问来源于stack exchange,提问作者satwell
相关产品推荐
相关产品推荐

