The title sort of says it all. I have a text file (NOT a perl file), which contains any number of placeholders over many lines and possibly several on the same line. Here's an example:
Hello ${first} ${last}, please visit us at http://${host}${context} and mind the \${variables}.
I need to replace everything that looks like ${...}
but not what looks like \${...}
. So this example needs to convert to:
Hello John Doe, please visit us at http://example.com/foobar and mind the \${variables}.
My expression currently looks like this:
s/([^\\])\$\{\s*([^\}\s]+)\s*\}/$1. _lookupVar( $2, $varMap )/ge
where _lookupVar
is a function that knows how to insert the right value. I have the first [^\\]
there in order to avoid replacing \${...}
sequences, but this means that for ${host}${context}
, only ${host}
gets replaced. And for various reasons, I can't really turn ${host}${context}
into ${host} ${context}
.
I can hack something, but I was wondering whether I'm missing some regex magic that somebody knowledgeable might like to teach me;-)
Use a negative lookbehind assertion (?<!\\)
rather than a negative character class [^\\]
:
s/(?<!\\)\$\{\s*([^\}\s]+)\s*\}/_lookupVar($1, $varMap)/ge
The character class consumes the character just behind the $
(resulting in you having to put it back with $1
), while the negative lookbehind simply checks to see if there's a \
there; if not, match the pattern.
To allow cases like:
\\${foo}
You could use something like:
s/(?<!\\)(?:\\\\)* \K \${ \s* ([^\s}]+) \s* }/_lookupVar($1, $varMap)/gxe
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.