Help with perl special variable

Discussion in 'Perl Misc' started by Ricky, Apr 11, 2012.

  1. Ricky

    Ricky Guest

    Hi gurus,
    I m reading a regexp and a string from an external file (actually my
    program configuration file).
    After, I need to do a string matching, using previously loaded regex,
    and print the "destination" result, using special variable $2,
    hardcoded in my conf.

    I have no luck..please give me some hints:

    Here is my configuration line:

    rule (^.*blabla-dir/blabla-file/)(.*$) /somedirectory/
    somefile/$2 LABEL

    perl code extract:
    ....
    /(^rule)\s+(.[^\s]+)\s+([\/\w\$]+)\s+(\w+)/
    $regex[$i]=$2;
    $destination[$i]=$3;
    ...
    ...
    $_="/blabla-dir/blabla-file/OIAC-ciao";
    if ( /$regex[$i]/ ) {
    print "$destination[$i]\n";
    }
    ...

    The print only show:
    /somedir/somepath/$2
    but I need to "explode" that $2. Note that if i modify the print as
    follows:

    print "$2 $destination[$i]\n";

    it returns:
    OIAC-ciao /somedir/somepath/$2

    I'm sure there is a way to do this..but I am a noob programmer

    Thanks,
    perlnoob
    Ricky, Apr 11, 2012
    #1
    1. Advertising

  2. Ricky

    Guest

    Il giorno mercoledì 11 aprile 2012 14:30:23 UTC+2, Ricky ha scritto:
    > Hi gurus,
    > I m reading a regexp and a string from an external file (actually my
    > program configuration file).
    > After, I need to do a string matching, using previously loaded regex,
    > and print the "destination" result, using special variable $2,
    > hardcoded in my conf.
    >
    > I have no luck..please give me some hints:
    >
    > Here is my configuration line:
    >
    > rule (^.*blabla-dir/blabla-file/)(.*$) /somedirectory/
    > somefile/$2 LABEL
    >
    > perl code extract:
    > ...
    > /(^rule)\s+(.[^\s]+)\s+([\/\w\$]+)\s+(\w+)/
    > $regex[$i]=$2;
    > $destination[$i]=$3;
    > ..
    > ..
    > $_="/blabla-dir/blabla-file/OIAC-ciao";
    > if ( /$regex[$i]/ ) {
    > print "$destination[$i]\n";
    > }
    > ..
    >
    > The print only show:
    > /somedir/somepath/$2
    > but I need to "explode" that $2. Note that if i modify the print as
    > follows:
    >
    > print "$2 $destination[$i]\n";
    >
    > it returns:
    > OIAC-ciao /somedir/somepath/$2
    >
    > I'm sure there is a way to do this..but I am a noob programmer
    >
    > Thanks,
    > perlnoob


    I tried the example in the FAQ with string substitution operator and modifier "eeg".No luck.
    I also tried to use "eval", and tried another approach to the problem. Still no luck.
    , Apr 11, 2012
    #2
    1. Advertising

  3. Ricky

    Guest

    Il giorno mercoledì 11 aprile 2012 16:14:06 UTC+2, ha scritto:
    > Il giorno mercoledì 11 aprile 2012 14:30:23 UTC+2, Ricky ha scritto:
    > > Hi gurus,
    > > I m reading a regexp and a string from an external file (actually my
    > > program configuration file).
    > > After, I need to do a string matching, using previously loaded regex,
    > > and print the "destination" result, using special variable $2,
    > > hardcoded in my conf.
    > >
    > > I have no luck..please give me some hints:
    > >
    > > Here is my configuration line:
    > >
    > > rule (^.*blabla-dir/blabla-file/)(.*$) /somedirectory/
    > > somefile/$2 LABEL
    > >
    > > perl code extract:
    > > ...
    > > /(^rule)\s+(.[^\s]+)\s+([\/\w\$]+)\s+(\w+)/
    > > $regex[$i]=$2;
    > > $destination[$i]=$3;
    > > ..
    > > ..
    > > $_="/blabla-dir/blabla-file/OIAC-ciao";
    > > if ( /$regex[$i]/ ) {
    > > print "$destination[$i]\n";
    > > }
    > > ..
    > >
    > > The print only show:
    > > /somedir/somepath/$2
    > > but I need to "explode" that $2. Note that if i modify the print as
    > > follows:
    > >
    > > print "$2 $destination[$i]\n";
    > >
    > > it returns:
    > > OIAC-ciao /somedir/somepath/$2
    > >
    > > I'm sure there is a way to do this..but I am a noob programmer
    > >
    > > Thanks,
    > > perlnoob

    >
    > I tried the example in the FAQ with string substitution operator and modifier "eeg".No luck.
    > I also tried to use "eval", and tried another approach to the problem. Still no luck.


    I saw the light..
    ...
    my $test=eval "\"$destination[$i]\"";
    print "$test\n";
    ...

    finally shows:
    /somedir/somepath/OIAC-ciao

    I really can't understand why it needs that kind of quoting ..
    Without it, doesn't works..
    Can someone explain??
    tks
    , Apr 11, 2012
    #3
  4. Ricky

    Guest

    Il giorno mercoledì 11 aprile 2012 18:37:43 UTC+2, Ben Morrow ha scritto:
    > Quoth :
    > >
    > > I saw the light..
    > > ..
    > > my $test=eval "\"$destination[$i]\"";
    > > print "$test\n";
    > > ..
    > >
    > > finally shows:
    > > /somedir/somepath/OIAC-ciao
    > >
    > > I really can't understand why it needs that kind of quoting ..
    > > Without it, doesn't works..
    > > Can someone explain??

    >
    > I can try... :).
    >
    > The first thing that happens is this
    >
    > "\"$destination[$i]\""
    >
    > string is evaluated. Since it's double-quoted, it interprets backslashes
    > specially and interpolates variables, so the result is the string
    >
    > '"/somedir/somepath/$2"'
    >
    > I've single-quoted that string to show that it won't be expanded again
    > (at least, not until you ask for it).
    >
    > The next thing that happens is that string is passed to eval. This looks
    > at the string and interprets it as a Perl expression, in this case the
    > expression
    >
    > "/somedir/somepath/$2"
    >
    > . Notice I've removed the single quotes, since this is no longer a
    > string *containing* a Perl expression, it's an actual Perl expression.
    > (This distinction is a little confusing, but is at the heart of what
    > eval does.)
    >
    > This expression is another double-quoted string, so again variables are
    > expanded and the result is
    >
    > '/somedir/somepath/OIAC-ciao'
    >
    > (I've single-quoted it for the same reason as before), which string is
    > then assigned to $test.


    Thanks m8. Your explainetion is great.

    > eval is much too powerful a tool for the job you are doing. Even if you
    > aren't worried about the security implications, the multiple layers of
    > quoting required get very confusing. Assuming you only want to support
    > numbered variables in your substitutions, I would use something like
    > this:
    >
    > if ( my @capture = /$regex[$i]/ ) {
    > my $result = $destination[$i];
    > $result =~ s/\$([0-9]+)/$capture[$1]/eg;
    > print "$result\n";
    > }
    >
    > This expands the variables in the result explicitly, rather than trying
    > to get perl to do it for you with eval.
    >
    > Ben


    I m now using following code:
    ...
    if ( my @capture = /$regex[$i]/ ) {
    my $result = $destination[$i];
    print "CAPTURE: @capture\n";
    print "BEFORE s//: $result\n";
    $result =~ s/\$([0-9]+)/$capture[$1-1]/eg;
    print "AFTER s//: $result\n";
    }
    ...

    And works fine.
    I only added "$1-1' cause "$1" will be out of index in @capture.
    This should be safer, and should work against any or multiple $[0-9] in my configuration line.

    Can you confirm?

    Thanks again Ben
    perlnoob.
    , Apr 12, 2012
    #4
  5. Ricky

    Tim McDaniel Guest

    In article <24881700.650.1334222359841.JavaMail.geo-discussion-forums@vbue17>,
    <> wrote:
    >I m now using following code:
    >..
    > if ( my @capture = /$regex[$i]/ ) {
    > my $result = $destination[$i];
    > print "CAPTURE: @capture\n";
    > print "BEFORE s//: $result\n";
    > $result =~ s/\$([0-9]+)/$capture[$1-1]/eg;
    > print "AFTER s//: $result\n";
    > }
    >..
    >
    >And works fine.
    >I only added "$1-1' cause "$1" will be out of index in @capture.
    >This should be safer, and should work against any or multiple $[0-9]
    >in my configuration line.


    I think it would be a little better if you sure that a reference is
    valid before referring to it.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

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

    my $regexp = '^(.)(.)'; # boobies!
    $_ = 'ABC';
    if (my @capture = /$regexp/) {
    my $result = 'left $1 right $2 invalid $3';
    print "CAPTURE: '", join("' '", @capture), "'\n";
    print "BEFORE s//: '$result'\n";
    my $bad = 0;
    foreach my $ref ($result =~ /\$([0-9]+)/g) {
    if (! exists $capture[$ref-1]) {
    warn "result '$result' refers to \$$ref, which is not captured in the regexp.\n";
    $bad = 1;
    }
    }
    if ($bad) {
    die "Dying due to bad element reference.\n";
    }
    $result =~ s/\$([0-9]+)/$capture[$1-1]/eg;
    print "AFTER s//: '$result'\n";
    }
    exit 0;


    --
    Tim McDaniel,
    Tim McDaniel, Apr 12, 2012
    #5
  6. Ricky

    Guest

    Il giorno giovedì 12 aprile 2012 18:01:13 UTC+2, Tim McDaniel ha scritto:
    > In article <24881700.650.1334222359841.JavaMail.geo-discussion-forums@vbue17>,
    > <> wrote:
    > >I m now using following code:
    > >..
    > > if ( my @capture = /$regex[$i]/ ) {
    > > my $result = $destination[$i];
    > > print "CAPTURE: @capture\n";
    > > print "BEFORE s//: $result\n";
    > > $result =~ s/\$([0-9]+)/$capture[$1-1]/eg;
    > > print "AFTER s//: $result\n";
    > > }
    > >..
    > >
    > >And works fine.
    > >I only added "$1-1' cause "$1" will be out of index in @capture.
    > >This should be safer, and should work against any or multiple $[0-9]
    > >in my configuration line.

    >
    > I think it would be a little better if you sure that a reference is
    > valid before referring to it.
    >
    > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    >
    > #! /usr/bin/perl
    > use strict;
    > use warnings;
    >
    > my $regexp = '^(.)(.)'; # boobies!
    > $_ = 'ABC';
    > if (my @capture = /$regexp/) {
    > my $result = 'left $1 right $2 invalid $3';
    > print "CAPTURE: '", join("' '", @capture), "'\n";
    > print "BEFORE s//: '$result'\n";
    > my $bad = 0;
    > foreach my $ref ($result =~ /\$([0-9]+)/g) {
    > if (! exists $capture[$ref-1]) {
    > warn "result '$result' refers to \$$ref, which is not captured in the regexp.\n";
    > $bad = 1;
    > }
    > }
    > if ($bad) {
    > die "Dying due to bad element reference.\n";
    > }
    > $result =~ s/\$([0-9]+)/$capture[$1-1]/eg;
    > print "AFTER s//: '$result'\n";
    > }
    > exit 0;
    >
    >
    > --
    > Tim McDaniel,


    Nice. I ll protect it using "exists".
    I love your regex :)

    tks
    , Apr 13, 2012
    #6
    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. dpackwood
    Replies:
    3
    Views:
    1,784
  2. Replies:
    13
    Views:
    531
    patelvijayp
    Apr 18, 2007
  3. Wes Gamble
    Replies:
    10
    Views:
    190
    Wes Gamble
    Oct 4, 2006
  4. Elephant
    Replies:
    2
    Views:
    153
    Web Surfer
    Mar 1, 2004
  5. Bart Van der Donck

    Special variable to read out ||-match

    Bart Van der Donck, Jun 1, 2006, in forum: Perl Misc
    Replies:
    3
    Views:
    99
    it_says_BALLS_on_your forehead
    Jun 5, 2006
Loading...

Share This Page