Search code examples
perlregexp-replaceubuntu-22.04

Perl: replace literal expression and literal variable names


When I use this expression:

echo '...${var}#other.([]);,=${var}#other${var}...' |
   perl -pe 's/\Q.([]);,=${var}\E/.([]);,=ok/'

As expected, the variable ${var} is expanded to "" (empty value) and the output is obtained:

...${var}#other.([]);,=ok${var}#other${var}...

but I want:

...${var}#other.([]);,=ok#other${var}...

So I thought about escaping the variable:

echo '...${var}#other.([]);,=${var}#other${var}...' |
   perl -pe 's/\Q.([]);,=\${var}\E/.([]);,=ok/'

For some reason that I don't know, the supplied string doesn't match a portion of the input one and it doesn't get replaced:

...${var}#other.([]);,=${var}#other${var}...

Double \\$ and triple \\\$ backslashes don't match either.
Where did I go wrong?


Solution

  • Per the perlop manpage (https://perldoc.perl.org/perlop):

    For the pattern of regex operators (qr//, m// and s///), the quoting from \Q is applied after interpolation is processed, but before escapes are processed. This allows the pattern to match literally (except for $ and @). For example, the following matches:

    '\s\t' =~ /\Q\s\t/
    

    Because $ or @ trigger interpolation, you'll need to use something like /\Quser\E\@\Qhost/ to match them literally.

    So, in your case, you might write:

    s/\Q.([])\E;,=\$\{var}/.([]);,=ok/