Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

Re: Re: How to remove the $1 hard coding

by tachyon (Chancellor)
on Aug 22, 2003 at 15:54 UTC ( [id://285831]=note: print w/replies, xml ) Need Help??


in reply to Re: How to remove the $1 hard coding
in thread How to remove the $1 hard coding

Elegant solution. Assuming that the search string is not $_ (and is $string) they probably want:

my @res = $string =~ m/\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*/ ; push @sps, $res[ $columnNumber ];

However a regex is total overkill when you could just:

@res = split ' ', $string; push @sps, $res[ $columnNumber ]; # or if you want one line push @sps, (split ' ', $string)[$columNumber];

Update

Fixed typo thanks chunlou

cheers

tachyon

s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

Replies are listed 'Best First'.
Re: Re: Re: How to remove the $1 hard coding
by MidLifeXis (Monsignor) on Aug 22, 2003 at 17:06 UTC

    The split is not the same as the pattern. The pattern uses \s* as the delimiter, which means that ABCD should match that pattern, as well as "A B C D".

    I just tested this, and it fails:

    push @sps, ($string =~ m/RE/)[$columnNumber];

    Could some fine monk explain why? Wouldn't the RE evaluate in a list context, which would then have an element extracted from it?

      The split is not the same as the pattern. The pattern uses \s* as the delimiter

      Well, actually, since the regex in the OP was:

      m/\s*(\S+)\s*(\S+)\s*(\S+)\s*(\S+)\s*/
      I was going to assert that this would generally be equivalent to splitting on whitespace, with the obvious difference that, if the string began with whitespace, split would return a list that included an empty string as the first element -- the first element returned by the regex would be the second element returned by split.

      But then I noticed another difference, which gave me pause, and I wondered if the OP had a clear grasp of the relevant detail -- that is, whether this regex is really doing what was intended. Consider the following:

      $s1="ABC D E"; $s2=" ABCD E "; # (leading and trailing spaces) print join( ":", split /\s+/, $s1 ), $/; print join( ":", split /\s+/, $s2 ), $/; print $/; print join( ":", ($s1=~/\s*(\S+)\s*(\S+)\s*(\S+)\s*/)), $/; print join( ":", ($s2=~/\s*(\S+)\s*(\S+)\s*(\S+)\s*/)), $/; __OUTPUT__ ABC:D:E :ABCD:E ABC:D:E ABC:D:E
      The first two lines of output show that split will return an empty string as the first list item if the string begins with a delimiter, whereas it will (by default) ignore trailing delimiters (but you can control that).

      The last two lines demonstrate the tenacity of the regex engine -- it does its best to match as much of the regex as possible. In this case, it takes the liberty of breaking up the "ABCD" portion of $s2, so that it can have non-empty values inside every set of capturing parens. The behavior is very different from split, indeed!

      Personally, I wouldn't feel comfortable using that particular regex pattern -- split seems more suitable.

        I was going to assert that this would generally be equivalent to splitting on whitespace, with the obvious difference that, if the string began with whitespace, split would return a list that included an empty string as the first element -- the first element returned by the regex would be the second element returned by split.

        You obviously didn't test it :-) split ' ' (as posted) is MAGICAL. It is not the same as split /\s*/.

        @v = split ' ', ' watch the magic '; print "$_: $v[$_]\n" for 0..$#v; print $/; @v = split /\s+/, ' lost the magic '; print "$_: $v[$_]\n" for 0..$#v; __DATA__ 0: watch 1: the 2: magic 0: 1: lost 2: the 3: magic

        As you see it is absolutely identical to the posted RE and drops leading whitespace.

        cheers

        tachyon

        s&&rsenoyhcatreve&&&s&n.+t&"$'$`$\"$\&"&ee&&y&srve&&d&&print

      Probably you meant this.
      push @a, ('a b c'=~/(\w) /g)[1]; print "@a";
      You need () to capture something into the array. You need the switch /g if you want to put every match into an array, not just the first match (hence for the index [$i] to work).
Re: Re: Re: How to remove the $1 hard coding
by chunlou (Curate) on Aug 22, 2003 at 16:04 UTC
    ...$string = m/...
                ^
                |
               typo?
    

      Updated: my bad, I misunderstood what the little arrow thing was supposed to point at.

      IIRC, m// is the regex matching quote. // is just a shorthand for it.

      cf. perlre

      </ajdelore>

        Not the m//, the = vs =~.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others examining the Monastery: (7)
As of 2024-04-24 21:25 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found