meonkeys has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to replace
<% $flat->purge('dynamix','outburst') %>

with
$CONFIG{DYNAMIX_OUTBURST}

like this
perl -pi.orig -e 's#<% \$flat->purge\('dynamix','outburst'\) %>#$CONFI +G{DYNAMIX_OUTBURST}#' www/index.html
with no luck. Any suggestions?

Replies are listed 'Best First'.
Re: Regex Help
by dchetlin (Friar) on Sep 23, 2000 at 04:47 UTC
    I imagine you're having quoting problems. Note that you're using ' as your shell quote, but you're searching for it in the REx.

    It will probably be easiest to use double quotes in the shell, although that will complicate things with the `$' in a REx.

    perl -pi.orig -e "s#<% \\\$flat->purge\('dynamix','outburst'\) %>#\$CONFIG{DYNAMIX_OUTBURST}#" www/index.html

      Ah! I think I've got it (with dchetlin's help)...
      The trick is to triple escape any $ characters
      perl -pi.orig -e "s#<% \\\$flat->purge\('dynamix','outburst'\) %>#\\\$ +CONFIG{DYNAMIX_OUTBURST}#" www/index.html
      This MAY be shell-dependant.
      Anyone know any more about this?

      Thank you! Note to self: "Boy, I love it when that dim bulb lights up. Must be Friday."
Re: Regex Help
by tye (Sage) on Sep 23, 2000 at 05:11 UTC

    Yes, some of this is shell dependant. I prefer using [x] over \x for escaping characters in regular expressions -- I just think it is easier to read (though it might make the regex slightly slower if the regex compiler doesn't optimize single-char classes -- I hadn't really worried about that before). It is unfortunate that the convoluted rules for detecting variable names inside regexes think [$] is trying to expand the variable $] so you can't use this trick to escape a dollar sign in a regexp.

    In most Unix shells, you can switch between quoting styles to make your life easier:

    perl -pi.orig -e 's#<% $flat->purge'"[(]'dynamix','outburst'[)] %>#"'$ +CONFIG{DYNAMIX_OUTBURST}#ge' www/index.html

    Under Win32, you'd use:

    perl -pi.orig -e "s#<% $flat->purge[(]'dynamix','outburst'[)] %>#$CONF +IG{DYNAMIX_OUTBURST}#ge" www/index.html

            - tye (but my friends call me "Tye")
      Unfortunately, Perl doesn't optimize [x]:

      [~] $ perl -Mre=debug -wle'"x" =~ /x/' Freeing REx: `,' Compiling REx `x' size 3 first at 1 rarest char x at 0 1: EXACT <x>(3) 3: END(0) anchored `x' at 0 (checking anchored isall) minlen 1 Omitting $` $& $' support. EXECUTING... Guessing start of match, REx `x' against `x'... Found anchored substr `x' at offset 0... Guessed: match at offset 0 Freeing REx: `x' [~] $ perl -Mre=debug -wle'"x" =~ /[x]/' Freeing REx: `,' Compiling REx `[x]' size 10 first at 1 1: ANYOF[x](10) 10: END(0) stclass `ANYOF[x]' minlen 1 Omitting $` $& $' support. EXECUTING... Matching REx `[x]' against `x' Setting an EVAL scope, savestack=3 0 <> <x> | 1: ANYOF[x] 1 <x> <> | 10: END Match successful! Freeing REx: `[x]'

      And in case that doesn't convince you:

      [~] $ perl -MBenchmark -we'timethese(-5,{x=>q{"x"=~/x/},"[x]"=>q{"x"=~ +/[x]/}})' Benchmark: running [x], x, each for at least 5 CPU seconds... [x]: 4 wallclock secs ( 5.23 usr + 0.00 sys = 5.23 CPU) @ 85 +2787.57/s (n=4460079) x: 6 wallclock secs ( 5.25 usr + 0.00 sys = 5.25 CPU) @ 14 +99188.19/s (n=7870738)

      P.S. I think you missed a backwhack in your RExen above; Perl is going to try to interpolate $flat.

Re: Regex Help
by eak (Monk) on Sep 23, 2000 at 04:55 UTC
    I like this better. You have to put the code in a file, but you don't have to escape the dollar sign three times.
    #!/usr/bin/perl -i.orig -w use strict; while(<>){ s/<% \$flat->purge\('dynamix','outburst'\) %>/\$CONFIG{DYNAMIX_OUTBU +RST}/g; print; }
      Hmm ... now I'm confused. The original post had $CONFIG{DYNAMIX_OUTBURST} without any escapes, leading me to believe that the value of $CONFIG{DYNAMIX_OUTBURST} was wanted in the file. But the followup to my post by the OP had it backwhacked, and so does this one.

      Do we want the value, or do we want the literal string?

      -dlc

        You have to escape the dollar sign to protect it from the shell.

        It just occurred to me that this is a case where s/// and s///e do exactly the same thing.

                - tye (but my friends call me "Tye")
        dchetlin said:
        Do we want the value, or do we want the literal string?
        and
        There's a discrepancy between the original post and those two posts wrt what behavior is wanted.

        Well, you ask excellent questions! I should have stated more clearly what I wanted. I wanted to replace this (literally)
        <% $flat->purge('dynamix','outburst') %>

        with this (literally)
        $CONFIG{DYNAMIX_OUTBURST}

        Sorry for the confusion. I didn't escape $CONFIG{DYNAMIX_OUTBURST} in the regex because I didn't know that it would be interpolated when using single quotes for the string that Perl will execute. I am curious as to the function of each individual backwhack.