in reply to How to remove the $1 hard coding

In general when you want to vary the name of a variable it's a sign you probably want an array or hash instead.

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

Update: As flounder99 notes (in the wrong direction :) you might need to adjust $columnNumber down by one to get the right index it starts at one rather than zero.

Replies are listed 'Best First'.
Re: Re: How to remove the $1 hard coding
by tachyon (Chancellor) on Aug 22, 2003 at 15:54 UTC

    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

      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.

        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).
      ...$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>

Re^2: How to remove the $1 hard coding
by flounder99 (Friar) on Aug 22, 2003 at 16:21 UTC
    I think you want
    push @sps, $res[ $columnNumber + 1 ];
    since abhishes was using $columnNumber == 2 for $2 then $columnNumber appears to be one-based not zero-based like an array.

    --

    flounder