in reply to Behavior of /g when there are capture groups

If you call the regex in scalar context (ex: as a conditional) /g will make it possible to work one match at a time, allowing you to have finer control over what you do with the captures.

#use Data::Dumper; my %res; while (/(fo.)(.*?)(ba.)/g) { $res{$&} = [ @-[1..3] ]; } print Dumper \%res;

Edit: the slice should be on indices 1..3, not 0..2.

Replies are listed 'Best First'.
Re^2: Behavior of /g when there are capture groups
by AnomalousMonk (Archbishop) on Apr 21, 2016 at 19:18 UTC

    This could be generalized to extract substrings, not just substring initial offsets; also to avoid  $& which just slows everything down. (The many evals might slow things down, though. Oh, well...) (Also tested under 5.8.9.)

    c:\@Work\Perl>perl -wMstrict -le "use Data::Dumper; ;; $_ = 'abcdfoofrobnicatebardefforspambazghi'; ;; my $re = qr{ (fo.) (.*?) (ba.) }xms; ;; my %res; while (/($re)/g) { $res{$1} = [ map eval qq{\$$_}, 2 .. $#- ]; } print Dumper \%res; " $VAR1 = { 'forspambaz' => [ 'for', 'spam', 'baz' ], 'foofrobnicatebar' => [ 'foo', 'frobnicate', 'bar' ] };


    Give a man a fish:  <%-{-{-{-<

      I should have tested my code, I got confused and thought @- held the submatches themselves, not the indexes. So I actually meant $res{$&} = [ $1, $2, $3]; but got lazy :). And $res{$1} = [ $2, $3, $4 ] works without $& with the extra parentheses.

      Your proposition has the benefit of not requiring to know the inner regex and its number of captures :)

Re^2: Behavior of /g when there are capture groups
by ExReg (Priest) on Apr 21, 2016 at 15:53 UTC

    Thanks! I was unaware of that trick.