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

Hello Monks- I am using the following substitution expression in my program `perl -pi.bak -e "s|$find|$replace|g" $_`; where $find='\\d{2}-\\d{2}-\\d{4}' When i use \\d{2}-\\d{2}-\\d{4} instead of $find in the some statement in backticks it works as expected but when i use $find it does not. I tried the e modifier but it still does not work. Thanks for your help in advance! -S

Replies are listed 'Best First'.
Re: Variable substitution
by ikegami (Patriarch) on Oct 20, 2009 at 21:25 UTC
    $find='\\d{2}-\\d{2}-\\d{4}'
    means $find contains
    \d{2}-\d{2}-\d{4}
    Now, since `` supports the same escapes as as "", "\" followed by a letter is either special or reserved depending on the letter. \d doesn't yet have a use, so it emits a warning ("Unrecognized escape \d passed through") and treats the letter as a non-letter: "d" is returned. That means you are executing
    perl -pi.bak -e "s|d{2}-d{2}-d{4}|...|g" ...

    Why don't you use

    my $find = '\\d{2}-\\d{2}-\\d{4}'; my $replace = '{date}'; s/$find/$replace/

    Update: If I were to speculate:

    To which you'll reply "So I can use $1"

    To which I'll reply. Well, you could use

    my $find = '(\\d{2}-\\d{2})-(\\d{4})'; my $replace = '$2-$1'; eval "s/\$find/$replace/"

    but that would be pretty dumb. You need a template system, and the Perl interpreter is not that. The one I've come across that best fits the current syntax is String::Interpolate.

Re: Variable substitution
by jwkrahn (Abbot) on Oct 20, 2009 at 21:23 UTC

    Are you running this in a shell script? Are you running this in a Python or Ruby or ?? program?

    The backquotes and the double quotes mean that your perl code is first interpolated by the shell and then interpolated by perl.

    You probably want something like this instead (UNTESTED):

    my $find = qr/\d{2}-\d{2}-\d{4}/; my $replace = 'something else'; { local ( $^I, @ARGV ) = ( '.bak', $_ ); while ( <> ) { s|$find|$replace|g; print; } }
Re: Variable substitution
by jakobi (Pilgrim) on Oct 20, 2009 at 21:26 UTC

    If you're indeed using `perl -e ...` from inside perl, you need to add an extra layer of backslashes, as you're forgetting to protect against the extra interpolation due to the shell: you're running perl, invoking the shell (``) which in turn invokes perl. And your variables, esp. $_ hopefully is something very simple that parses as a single shell word.

    (In case you're invoking `perl` from a shell script, just export $file, and you can then access the variable's content in Perl using $ENV{file})

    Either way, do consider using single quotes instead of your double quote: `perl -e '...'`, which allows you to get rid of some backslashes...

    HTH
    Peter

        But your regex contains .* and this results in just the four letter word RTFM, which I hate with a passion in its standalone version.

        Shouldn't we all remember that RTFM is a protocol prefix and requires an obligatorie MEME URI which provides at least an additional hint or keyword?

        So the proper use should be a still sufficiently terse RTFM://<check_both_quoting_and_consider_rethinking_your_approach>.

        ;>
        Peter (who is a bit ashamed to have failed roboticus' elegance & brevity test)