Using match variables ($1, $2 ...) as variables.

Discussion in 'Perl Misc' started by Ravi Parimi, May 11, 2004.

  1. Ravi Parimi

    Ravi Parimi Guest

    Hi,
    I have a string that gets generated on the fly. Based on the
    number of times a particular word appears in this string, I generate my
    matching pattern. As an example..

    $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    string</Data>";

    Now, based on the number of <Size> tags in the string, I create a regular
    expression such as

    my $count = $string =~ s#<Size>##gs;
    my $str = "";
    for ($i = 1;$i <= $count;++$count) {
    $str .= "<Size>(\\d+)</Size>(.*)";
    }

    And now I wish to extract all odd-numbered match variables from the
    matching($1, $3, $5 etc..)

    $string =~ /$str/; # Match always succeeds as I know what's in $string

    In a for loop, I wish to check if each of the $1,$2,$3...variables are
    defined, and am not quite sure how to do that.


    Usage of ${$i} is incorrect and doesnt make sense. Can someone suggest a
    method by which I can find out if $1, $2, $3 ..are defined?


    As an alternative, I have tried XML Parser to parse the above string but
    had no luck with it.. Any help is appreciated.

    Thanks,
    --ravi
     
    Ravi Parimi, May 11, 2004
    #1
    1. Advertising

  2. Ravi Parimi

    Bob Walton Guest

    Ravi Parimi wrote:

    ....
    > I have a string that gets generated on the fly. Based on the
    > number of times a particular word appears in this string, I generate my
    > matching pattern. As an example..
    >
    > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > string</Data>";
    >
    > Now, based on the number of <Size> tags in the string, I create a regular
    > expression such as
    >
    > my $count = $string =~ s#<Size>##gs;



    Why do you have the "s" modifier on this regexp? You don't use the .
    metacharacter in it, and the "s" modifiers only purpose is to change the
    behavior of the . metacharacter.


    > my $str = "";
    > for ($i = 1;$i <= $count;++$count) {



    Hmmmmm...if $count is, for example, 3, then this will loop forever
    (well, until overflow, anyway), as $i will remain 1 and count will
    increment to 4, 5, 6, etc. What is your real code?


    > $str .= "<Size>(\\d+)</Size>(.*)";
    > }
    >
    > And now I wish to extract all odd-numbered match variables from the
    > matching($1, $3, $5 etc..)
    >
    > $string =~ /$str/; # Match always succeeds as I know what's in $string
    >
    > In a for loop, I wish to check if each of the $1,$2,$3...variables are
    > defined, and am not quite sure how to do that.
    >
    >
    > Usage of ${$i} is incorrect and doesnt make sense. Can someone suggest a
    > method by which I can find out if $1, $2, $3 ..are defined?
    >



    Check out:

    perldoc perlvar

    in particular the part where it talks about the @- and @+ variables.
    These give you programmatic access to the $1, $2, etc variables, via
    substr() and the variable you matched the pattern against.


    >
    > As an alternative, I have tried XML Parser to parse the above string but
    > had no luck with it.. Any help is appreciated.
    >

    ....
    > --ravi


    --
    Bob Walton
    Email: http://bwalton.com/cgi-bin/emailbob.pl
     
    Bob Walton, May 11, 2004
    #2
    1. Advertising

  3. Also sprach Ravi Parimi:

    > I have a string that gets generated on the fly. Based on the
    > number of times a particular word appears in this string, I generate my
    > matching pattern. As an example..
    >
    > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > string</Data>";
    >
    > Now, based on the number of <Size> tags in the string, I create a regular
    > expression such as
    >
    > my $count = $string =~ s#<Size>##gs;
    > my $str = "";
    > for ($i = 1;$i <= $count;++$count) {
    > $str .= "<Size>(\\d+)</Size>(.*)";
    > }
    >
    > And now I wish to extract all odd-numbered match variables from the
    > matching($1, $3, $5 etc..)
    >
    > $string =~ /$str/; # Match always succeeds as I know what's in $string
    >
    > In a for loop, I wish to check if each of the $1,$2,$3...variables are
    > defined, and am not quite sure how to do that.


    A more natural solution would be changing the pattern accordingly. You
    always add two pairs of capturing parens. What is the second pair for?

    Other than that, do the pattern match in list context and extract the
    uneven elements from the array:

    my @matches = $string =~ /$str/;
    @matches = map { $_ % 2 ? $matches[$_] : () } 0 .. $#matches;

    Tassilo
    --
    $_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
    pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
    $_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
     
    Tassilo v. Parseval, May 11, 2004
    #3
  4. Ravi Parimi

    gnari Guest

    "Tassilo v. Parseval" <> wrote in message
    news:...
    > Also sprach Ravi Parimi:
    >
    > > I have a string that gets generated on the fly. Based on the
    > > number of times a particular word appears in this string, I generate my
    > > matching pattern. As an example..
    > >
    > > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > > string</Data>";
    > >
    > > my $count = $string =~ s#<Size>##gs;
    > > my $str = "";
    > > for ($i = 1;$i <= $count;++$count) {
    > > $str .= "<Size>(\\d+)</Size>(.*)";
    > > }


    > my @matches = $string =~ /$str/;
    > @matches = map { $_ % 2 ? $matches[$_] : () } 0 .. $#matches;


    exept that the greedy (.*) will spoin the match it there are more that
    2 pairs of the tags.

    I would skip the pattern building and just do (untested):
    my @matches = $string =~ /<Size>(\d+)</Size>([^<]*)/gs;
    and then process the array similarly to Tassilo.

    gnari
     
    gnari, May 11, 2004
    #4
  5. gnari <> wrote:

    > my @matches = $string =~ /<Size>(\d+)</Size>([^<]*)/gs;



    m//s only affects dot.

    You never need a m//s when there is no dot in the pattern.


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, May 11, 2004
    #5
  6. Ravi Parimi

    GreenLight Guest

    Ravi Parimi <> wrote in message news:<>...
    > Hi,
    > I have a string that gets generated on the fly. Based on the
    > number of times a particular word appears in this string, I generate my
    > matching pattern. As an example..
    >
    > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > string</Data>";
    >
    > Now, based on the number of <Size> tags in the string, I create a regular
    > expression such as
    >
    > my $count = $string =~ s#<Size>##gs;
    > my $str = "";
    > for ($i = 1;$i <= $count;++$count) {
    > $str .= "<Size>(\\d+)</Size>(.*)";
    > }
    >
    > And now I wish to extract all odd-numbered match variables from the
    > matching($1, $3, $5 etc..)
    >
    > $string =~ /$str/; # Match always succeeds as I know what's in $string
    >
    > In a for loop, I wish to check if each of the $1,$2,$3...variables are
    > defined, and am not quite sure how to do that.
    >
    >
    > Usage of ${$i} is incorrect and doesnt make sense. Can someone suggest a
    > method by which I can find out if $1, $2, $3 ..are defined?
    >
    >
    > As an alternative, I have tried XML Parser to parse the above string but
    > had no luck with it.. Any help is appreciated.
    >
    > Thanks,
    > --ravi


    Perhaps you are trying to overcomplicate the solution. Look at this:

    my $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    string</Data>"; # <-- this string should not be wrapped
    my @rows = ($string =~ /<Size>(\d+)<\/Size>/gi);
    foreach (@rows) {
    print "$_\n";
    }

    That snippet of code produces this:
    12
    100

    When you capture the result of the pattern match ("my @rows =...") in
    list context, you get all of the matches as a list.

    Is that what you want to accomplish?
    --
    my real address is perl - at - milbaugh - dot - com
     
    GreenLight, May 11, 2004
    #6
  7. Ravi Parimi

    gnari Guest

    "Tad McClellan" <> wrote in message
    news:...
    > gnari <> wrote:
    >
    > > my @matches = $string =~ /<Size>(\d+)</Size>([^<]*)/gs;

    >
    >
    > m//s only affects dot.
    >
    > You never need a m//s when there is no dot in the pattern.


    yep. had started with (.*), and changed it to ([^<]*) ,but
    forgot to take the /s out.
     
    gnari, May 11, 2004
    #7
  8. Ravi Parimi

    Uri Guttman Guest

    >>>>> "g" == gnari <> writes:

    g> "Tad McClellan" <> wrote in message
    g> news:...
    >> gnari <> wrote:
    >>
    >> > my @matches = $string =~ /<Size>(\d+)</Size>([^<]*)/gs;

    >>
    >>
    >> m//s only affects dot.
    >>
    >> You never need a m//s when there is no dot in the pattern.


    g> yep. had started with (.*), and changed it to ([^<]*) ,but
    g> forgot to take the /s out.

    i have been there and done that. :)

    that is a useful regex transform to know. mastering regular expressions
    covers it well.

    uri

    --
    Uri Guttman ------ -------- http://www.stemsystems.com
    --Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
    Search or Offer Perl Jobs ---------------------------- http://jobs.perl.org
     
    Uri Guttman, May 11, 2004
    #8
  9. Ravi Parimi

    Ravi Parimi Guest

    > > Hi,
    > > I have a string that gets generated on the fly. Based on the
    > > number of times a particular word appears in this string, I generate my
    > > matching pattern. As an example..
    > >
    > > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > > string</Data>";
    > >
    > > Now, based on the number of <Size> tags in the string, I create a regular
    > > expression such as
    > >
    > > my $count = $string =~ s#<Size>##gs;
    > > my $str = "";
    > > for ($i = 1;$i <= $count;++$count) {
    > > $str .= "<Size>(\\d+)</Size>(.*)";
    > > }
    > >
    > > And now I wish to extract all odd-numbered match variables from the
    > > matching($1, $3, $5 etc..)
    > >
    > > $string =~ /$str/; # Match always succeeds as I know what's in $string
    > >
    > > In a for loop, I wish to check if each of the $1,$2,$3...variables are
    > > defined, and am not quite sure how to do that.
    > >
    > >
    > > Usage of ${$i} is incorrect and doesnt make sense. Can someone suggest a
    > > method by which I can find out if $1, $2, $3 ..are defined?
    > >
    > >
    > > As an alternative, I have tried XML Parser to parse the above string but
    > > had no luck with it.. Any help is appreciated.
    > >
    > > Thanks,
    > > --ravi

    >
    > Perhaps you are trying to overcomplicate the solution. Look at this:
    >
    > my $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > string</Data>"; # <-- this string should not be wrapped
    > my @rows = ($string =~ /<Size>(\d+)<\/Size>/gi);
    > foreach (@rows) {
    > print "$_\n";
    > }
    >
    > That snippet of code produces this:
    > 12
    > 100
    >
    > When you capture the result of the pattern match ("my @rows =...") in
    > list context, you get all of the matches as a list.
    >
    > Is that what you want to accomplish?


    This was what I was exactly looking for. It looks a lot more less
    complicated than what the other posters suggested. Thanks a lot for your
    help :)

    --ravi
     
    Ravi Parimi, May 11, 2004
    #9
  10. Ravi Parimi

    Ravi Parimi Guest

    > ...
    > > I have a string that gets generated on the fly. Based on the
    > > number of times a particular word appears in this string, I generate my
    > > matching pattern. As an example..
    > >
    > > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > > string</Data>";
    > >
    > > Now, based on the number of <Size> tags in the string, I create a regular
    > > expression such as
    > >
    > > my $count = $string =~ s#<Size>##gs;

    >
    >
    > Why do you have the "s" modifier on this regexp? You don't use the .
    > metacharacter in it, and the "s" modifiers only purpose is to change the
    > behavior of the . metacharacter.



    It was a typo. I should've posted my complete code rather than typing
    snippets here and there..

    > Check out:
    >
    > perldoc perlvar
    >
    > in particular the part where it talks about the @- and @+ variables.
    > These give you programmatic access to the $1, $2, etc variables, via
    > substr() and the variable you matched the pattern against.


    Thanks for the pointer to perlvar. I didnt know that @-,@+ existed prior
    to reading this.

    --ravi
     
    Ravi Parimi, May 11, 2004
    #10
  11. Ravi Parimi

    Ravi Parimi Guest

    > > I have a string that gets generated on the fly. Based on the
    > > number of times a particular word appears in this string, I generate my
    > > matching pattern. As an example..
    > >
    > > $string = "<Data><Size>12</Size>one string<Size>100</Size>Another
    > > string</Data>";
    > >
    > > Now, based on the number of <Size> tags in the string, I create a regular
    > > expression such as
    > >
    > > my $count = $string =~ s#<Size>##gs;
    > > my $str = "";
    > > for ($i = 1;$i <= $count;++$count) {
    > > $str .= "<Size>(\\d+)</Size>(.*)";
    > > }
    > >
    > > And now I wish to extract all odd-numbered match variables from the
    > > matching($1, $3, $5 etc..)
    > >
    > > $string =~ /$str/; # Match always succeeds as I know what's in $string
    > >
    > > In a for loop, I wish to check if each of the $1,$2,$3...variables are
    > > defined, and am not quite sure how to do that.

    >
    > A more natural solution would be changing the pattern accordingly. You
    > always add two pairs of capturing parens. What is the second pair for?
    >
    > Other than that, do the pattern match in list context and extract the
    > uneven elements from the array:
    >
    > my @matches = $string =~ /$str/;
    > @matches = map { $_ % 2 ? $matches[$_] : () } 0 .. $#matches;


    You solution also worked for me prefectly. Thanks a lot for your reply!
    I took care of the greedy matching problem as suggested by Gnari and Tad.

    --ravi
     
    Ravi Parimi, May 11, 2004
    #11
  12. Ravi Parimi <> wrote:

    > I should've posted my complete code rather than typing
    > snippets here and there..



    Have you seen the Posting Guidelines that are posted here frequently?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, May 12, 2004
    #12
  13. Ravi Parimi <> wrote:


    [ snip 50-line full-quote with no attribution.
    Please learn how to properly compose a followup.
    Please do this soon.
    ]


    > This was what I was exactly looking for. It looks a lot more less

    ^^^^ ^^^^
    ^^^^ ^^^^
    > complicated than what the other posters suggested.



    Huh?


    --
    Tad McClellan SGML consulting
    Perl programming
    Fort Worth, Texas
     
    Tad McClellan, May 12, 2004
    #13
  14. Ravi Parimi

    Ravi Parimi Guest

    > Ravi Parimi <> wrote:
    >
    >
    > [ snip 50-line full-quote with no attribution.
    > Please learn how to properly compose a followup.
    > Please do this soon.
    > ]


    Sorry about that.
    >
    > > This was what I was exactly looking for. It looks a lot more less

    > ^^^^ ^^^^
    > ^^^^ ^^^^
    > > complicated than what the other posters suggested.


    >
    > Huh?


    I wanted to write "a lot less complicated".

    --ravi
     
    Ravi Parimi, May 12, 2004
    #14
  15. [A complimentary Cc of this posting was sent to
    Ravi Parimi
    <>], who wrote in article <>:

    > Usage of ${$i} is incorrect and doesnt make sense.


    Could you elaborate on this point?

    >perl -wle "'abcde' =~ /(.)c(.)/ or die; $v=2; print $$v"

    d

    Yours,
    Ilya
     
    Ilya Zakharevich, May 13, 2004
    #15
  16. In article <c7us1e$1m6r$>, Ilya Zakharevich wrote:
    > [A complimentary Cc of this posting was sent to
    > Ravi Parimi
    ><>], who wrote in article
    ><>:
    >
    >> Usage of ${$i} is incorrect and doesnt make sense.

    >
    > Could you elaborate on this point?
    >
    > >perl -wle "'abcde' =~ /(.)c(.)/ or die; $v=2; print $$v"

    > d


    And ${$v} is another way of writing $$v... see 'perldoc perlref', specifically
    item #2 under section "Using References".

    Kevin
     
    Kevin Collins, May 13, 2004
    #16
  17. Ravi Parimi

    Thomas Kratz Guest

    Kevin Collins wrote:

    > In article <c7us1e$1m6r$>, Ilya Zakharevich wrote:
    >
    >>[A complimentary Cc of this posting was sent to
    >>Ravi Parimi
    >><>], who wrote in article
    >><>:
    >>
    >>
    >>>Usage of ${$i} is incorrect and doesnt make sense.

    >>
    >>Could you elaborate on this point?
    >>
    >> >perl -wle "'abcde' =~ /(.)c(.)/ or die; $v=2; print $$v"

    >> d

    >
    >
    > And ${$v} is another way of writing $$v... see 'perldoc perlref', specifically
    > item #2 under section "Using References".


    You are missing the point. Ilya just wanted to know how the usage of ${$i}
    is incorrect or doesn't make sense. And he provided a syntactically
    correct example, that does make some sense (for arbitrary values of sense).

    Thomas

    --
    open STDIN,"<&DATA";$=+=14;$%=50;while($_=(seek( #J~.> a>n~>>e~.......>r.
    STDIN,$:*$=+$,+$%,0),getc)){/\./&&last;/\w| /&&( #.u.t.^..oP..r.>h>a~.e..
    print,$_=$~);/~/&&++$:;/\^/&&--$:;/>/&&++$,;/</ #.>s^~h<t< ..~. ...c.^..
    &&--$,;$:%=4;$,%=23;$~=$_;++$i==1?++$,:_;}__END__#....>>e>r^..>l^...>k^..
     
    Thomas Kratz, May 13, 2004
    #17
    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. hiwa
    Replies:
    0
    Views:
    640
  2. Victor
    Replies:
    2
    Views:
    649
    Victor
    May 17, 2004
  3. ekzept
    Replies:
    0
    Views:
    377
    ekzept
    Aug 10, 2007
  4. John Gordon
    Replies:
    13
    Views:
    490
    Ian Kelly
    Dec 20, 2011
  5. Volkan Civelek

    Match doesn't match

    Volkan Civelek, Jul 19, 2006, in forum: Ruby
    Replies:
    4
    Views:
    168
Loading...

Share This Page