I'm trying to implement simple shell-style string variable interpolation with $varname syntax, using pyparsing. For example, if I have a variable foo
with value "bar"
, then transform "x $foo x"
to "x bar x"
.
But I'd like to prevent variable interpolation when the $
has a backslash in front. So "x \$foo x"
should stay "x \$foo x"
. I'm using pyparsing's transform_string
. I tried to add negative lookahead to avoid parsing a string that starts with \
. But it's not working.
import pyparsing as pp
vars = {"foo": "bar"}
interp = pp.Combine(
~pp.Literal("\\")
+ pp.Literal("$").suppress()
+ pp.common.identifier.set_parse_action(lambda t: vars[t[0]])
)
print(interp.transform_string("x $foo x"))
print(interp.transform_string("x \\$foo x"))
This outputs:
x bar x
x \bar x
But I'd like it to output:
x bar x
x \$foo x
I suspect negative lookahead at the beginning of a parser doesn't work with transform_string
because it can still find a substring without the \
that parses. But I'm not sure how to fix this.
Glad you resolved your issue. To answer your original question, I was able to fix it by changing your expression to this (essentially a negative lookbehind):
interp = pp.Combine(
~pp.PrecededBy("\\")
+ pp.Literal("$").suppress()
+ pp.common.identifier.set_parse_action(lambda t: vars[t[0]])
)