Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: Perl oddities

by YuckFoo (Abbot)
on Mar 01, 2005 at 18:53 UTC ( #435571=note: print w/ replies, xml ) Need Help??


in reply to Perl oddities

It is odd that regex capture variables are not put in an array somewhere and I have to explicitly list them:

# too much work... my ($this, $that, $some, $other) = ($1, $2, $3, $4); # would rather: my ($this, $that, $some, $other) = @_;

YuckFoo


Comment on Re: Perl oddities
Download Code
Re^2: Perl oddities
by gaal (Parson) on Mar 01, 2005 at 19:16 UTC
    Often you can just assign the results of the match. Make sure you are in list context if you have only one capture.

    my ($this, $that, $some, $other) = /(this)(that).*(some)....(other)$/; my ($cap) = /hello(there)/; # OK my $cap = /hello(there)/; # BUG
      Often you can just assign the results of the match.

      But not if you use /g, as /g acts quite differently in scalar and in list context.

Re^2: Perl oddities
by Not_a_Number (Parson) on Mar 01, 2005 at 19:36 UTC

    I generally do as gaal suggests. However, if this were impossible, and if you had a long list of regex capture variables, you could always do:

       my ( $this, $that, $some, $other, $foo, $bar, $baz ) = ( $1 .. $+ );

    dave

      I am aware of the method suggested by gaal. I usually do not use it because I almost always wrap the regex up with an 'if'. Throw in a my function and it starts to get messy.
      # Ugly to me... if (my ($this, $that, $some, $other) = $line =~ /(this).*(that).*(some +).*(other)/) { do_it(); }; # Better, I think... if ($line =~ /(this).*(that).*(some).*(other)/) { my ($this, $that, $some, $other) = ($1, $2, $3, $4); do_it(); }
      This business doesn't DWYM:

      my ( $this, $that, $some, $other, $foo, $bar, $baz ) = ( $1 .. $+ );
      The magical string incrementer is summoned to build a list of strings starting with the first capture, ending with the last.

      YuckFoo

        You can do

        if (my @r = $line =~ /(this).*(that).*(some).*(other)/) { my ($this, $that, $some, $other) = @r; do_it(); }
        if you want the conditional expression shorter and don't want to repeat the dollar-digit vars.

        ihb

        See perltoc if you don't know which perldoc to read!

      That doesn't work:
      #!/usr/bin/perl use strict; use warnings; $_ = "this that some other foo bar baz"; if (/(this)\s*(that)\s*(some)\s*(other)\s*(foo)\s*(bar)\s*(baz)/) { my ($this, $that, $some, $other, $foo, $bar, $baz) = ($1 .. $+); print "$this, $that, $some, $other, $foo, $bar, $baz\n"; } __END__ Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at Use of uninitialized value in concatenation (.) or string at , , , , , ,
      What does work is:
      #!/usr/bin/perl use strict; use warnings; $_ = "this that some other foo bar baz"; if (/(this)\s*(that)\s*(some)\s*(other)\s*(foo)\s*(bar)\s*(baz)/) { my ($this, $that, $some, $other, $foo, $bar, $baz) = map {;no strict 'refs'; $$_} 1 .. $#-; print "$this, $that, $some, $other, $foo, $bar, $baz\n"; } __END__ this, that, some, other, foo, bar, baz
      A trick I've been using for quite a long time. ($#+ instead of $#- works as well).
Re^2: Perl oddities
by TimToady (Parson) on Mar 01, 2005 at 21:32 UTC
    This also is fixed in Perl 6. You can get at the captures as an array if you like, or you can even bind the variables directly within the pattern and bypass the assignment altogether (though you'd still have to declare the variables in that case). Alternately, you can name the captures within the pattern and then get at them as a hash. With some syntactic sugar, $1 is also called $<this>, $2 is also called $<that>, etc., and it's just pulling captures out of the result object without you having to declare anything (except the name bindings within the pattern).

    A few other pattern matching things have changed too. :-)

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://435571]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (7)
As of 2014-12-25 02:37 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    Is guessing a good strategy for surviving in the IT business?





    Results (159 votes), past polls