You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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"))

代码说明

  1. escaped_dollar:专门匹配\$,解析时直接返回原字符串,保证转义后的$不被替换。
  2. var_ref:
    • ~pp.PrecededBy(pp.Literal("\\")):用负前置检查确保$的前一个字符不是反斜杠;
    • 匹配$并忽略它,接着匹配标识符,最后通过parse_action替换为变量值。
  3. interp:用ZeroOrMore遍历整个字符串,依次处理转义$、变量引用,剩下的普通字符(包括非$、非\的可打印字符和空白)直接保留。

输出结果

x bar x
x \$foo x

内容的提问来源于stack exchange,提问作者satwell

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 17:16:20