ARGV interpretation in s///

Discussion in 'Perl Misc' started by Just in, Sep 29, 2005.

  1. Just in

    Just in Guest

    I'm trying to write regexp search and replace strings on the command line
    and have the program I'm calling use them in a substitution. Problem is that
    the $[0-9] variables are not being interpreted the way I want them to be.

    Heres what I am doing on my Linux box:-

    <OUTPUT>
    %> try.pl -f to.txt -s 'add (\w+) minus' -r 'FOO$1BAR'
    FOO$1BAR
    FOO$1BAR
    %>
    </OUTPUT>

    <CODE>
    #!/usr/bin/perl
    use strict;
    use warnings;
    use Getopt::Std;

    # Variable declaration
    my $Search = my $Replace = my $File = '';

    # Process @ARGV
    getopts('f:hr:s:');
    our($opt_f, $opt_r, $opt_s);

    $opt_f ? $File = $opt_f : &DisplayHelp();
    $opt_r ? $Replace = $opt_r : &DisplayHelp();
    $opt_s ? $Search = $opt_s : &DisplayHelp();

    open(FILE, $File) or die "Can't open $File:- $!";
    while(<FILE>)
    {
    s/$Search/$Replace/;
    print;
    }
    close FILE;

    sub DisplayHelp
    {
    print "To be defined\n";
    exit 0;
    }
    </CODE>

    How can I achieve the desired interpretation of $1? Single quotes and double
    quotes don't help, nor does qr//

    Cheers

    Just in
    Just in, Sep 29, 2005
    #1
    1. Advertising

  2. Just in

    Paul Lalli Guest

    Just in wrote:
    > I'm trying to write regexp search and replace strings on the command line
    > and have the program I'm calling use them in a substitution. Problem is that
    > the $[0-9] variables are not being interpreted the way I want them to be.


    You have mis-diagnosed your problem. The fact that you are reading
    your replacement string from the command line is irrelevant to the
    issue at hand. Your goal is to get Perl to understand that a string
    containing the characters '$1' should in fact be evaluated as
    containing the string residing in the variable $1.

    As I was playing with a condensed version of your script, I eventually
    stumbled on to the answer. Unfortunately, I do not at all understand
    the answer. I found that if I add double quotes surrounding the
    Replacement string, and use a double /e modifier on the regexp, then $1
    becomes correctly interpolated.

    I'm hoping someone else in this group can explain to me why this works,
    or better yet, why *doesn't* a simple single /e without the extra
    double quotes, or even a /ee without the extra double quotes. Why are
    the two evals and the double quotes all necessary?

    Here is a short-but-complete script that illustrates the solution I
    found:

    #!/usr/bin/perl
    use strict;
    use warnings;

    my $Replace = 'FOO$1BAR';
    my $Search = 'add (\w+) minus';

    $Replace = qq{"$Replace"};

    while(<DATA>){
    if (s/$Search/$Replace/ee) {
    print;
    }
    }

    __DATA__
    add stuff minus
    add other_stuff minus


    Paul Lalli
    Paul Lalli, Sep 29, 2005
    #2
    1. Advertising

  3. Just in <> wrote:

    > Problem is that
    > the $[0-9] variables are not being interpreted the way I want them to be.




    > s/$Search/$Replace/;


    > How can I achieve the desired interpretation of $1?



    $Replace = qq("$Replace");
    s/$Search/$Replace/ee;


    See also:

    perldoc -q expand

    How can I expand variables in text strings?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 29, 2005
    #3
  4. Just in wrote:

    > I'm trying to write regexp search and replace strings on the command line
    > and have the program I'm calling use them in a substitution. Problem is that
    > the $[0-9] variables are not being interpreted the way I want them to be.


    Please see my "History of a FAQ" lightning talk about this question...

    http://birmingham.pm.org/talks/faq/Hello.html
    Brian McCauley, Sep 29, 2005
    #4
  5. Paul Lalli <> wrote:

    > I'm hoping someone else in this group can explain to me why this works,
    > or better yet, why *doesn't* a simple single /e without the extra
    > double quotes, or even a /ee without the extra double quotes. Why are
    > the two evals and the double quotes all necessary?



    The replacement string part of s/// is double quotish (by default),
    ie. with implied double quotes.

    So, (with the implied quotes shown) it looks like this to perl:

    "$Replace"

    perl does the indicated interpolation to determine the string to
    use as the replacement.


    Using the s///e modifier changes the above mentioned default so
    that the replacement part is code rather than a string.

    In that case, perl sees:

    $Replace

    so it evaluates that (simple) expression, no interpolation going on here.


    With s///ee, the 1st eval sees:

    $Replace

    as in the s///e case above. After evaluating that, the 2nd eval sees:

    FOO$1BAR

    bareword, variable, bareword. And confusion ensues.


    So, adding the double quotes to the value in $Replace would make
    the 2nd eval see:

    "FOO$1BAR"

    perl does the indicated interpolation to determine the string to
    use as the replacement.



    Note that, though it doesn't apply in this case since the values
    are coming from the command line anyway, but what would the
    2nd eval is s///ee see (and evaluate) if $Replace should
    ever get a value like:

    $Replace = 'unlink <* .*>';

    ??


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
    Tad McClellan, Sep 29, 2005
    #5
  6. Just in

    Paul Lalli Guest

    Tad McClellan wrote:
    > Paul Lalli <> wrote:
    >
    > > I'm hoping someone else in this group can explain to me why this works,
    > > or better yet, why *doesn't* a simple single /e without the extra
    > > double quotes, or even a /ee without the extra double quotes. Why are
    > > the two evals and the double quotes all necessary?



    > With s///ee, the 1st eval sees:
    >
    > $Replace
    >
    > as in the s///e case above. After evaluating that, the 2nd eval sees:
    >
    > FOO$1BAR
    >
    > bareword, variable, bareword. And confusion ensues.
    >
    >
    > So, adding the double quotes to the value in $Replace would make
    > the 2nd eval see:
    >
    > "FOO$1BAR"
    >
    > perl does the indicated interpolation to determine the string to
    > use as the replacement.


    Tad,

    Thank you very much for the very detailed explanation. I believe I now
    understand the situation.

    Much obliged,
    Paul Lalli
    Paul Lalli, Sep 29, 2005
    #6
  7. Tad McClellan wrote:

    > Just in <> wrote:
    >
    >>Problem is that
    >>the $[0-9] variables are not being interpreted the way I want them to be.

    >
    >> s/$Search/$Replace/;

    >
    >>How can I achieve the desired interpretation of $1?

    >
    > $Replace = qq("$Replace");
    > s/$Search/$Replace/ee;


    Once again, can I ask people not post this "simple, obvious, and
    wrong"[1] response to this question without mentioning the hazards of
    eval() and also pointing out how to avoid the problem with " characters
    in $Replace.

    [1] http://birmingham.pm.org/talks/faq/Answer.html
    Brian McCauley, Sep 30, 2005
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Bret

    char **argv vs. char* argv[]

    Bret, Aug 31, 2003, in forum: C Programming
    Replies:
    21
    Views:
    4,581
    Richard Heathfield
    Sep 3, 2003
  2. David
    Replies:
    10
    Views:
    5,949
    Richard Heathfield
    Sep 15, 2003
  3. Hal Styli
    Replies:
    14
    Views:
    1,627
    Old Wolf
    Jan 20, 2004
  4. =?ISO-8859-1?Q?Thomas_N=FCcker?=

    sys.argv[0] - 'module' object has no attribute 'argv'

    =?ISO-8859-1?Q?Thomas_N=FCcker?=, Jun 30, 2003, in forum: Python
    Replies:
    0
    Views:
    900
    =?ISO-8859-1?Q?Thomas_N=FCcker?=
    Jun 30, 2003
  5. jab3

    char **argv & char *argv[]

    jab3, Dec 4, 2004, in forum: C Programming
    Replies:
    5
    Views:
    664
    Chris Torek
    Dec 8, 2004
Loading...

Share This Page