in reply to Global regexp

The Perl regular expression engine starts the next match always after the last matched character of the previous match. So you will need lookahead assertions (?= that don't adjust pos if you don't want to fiddle with pos yourself (see perlre on lookahead assertions):

perl -le "$_='1234';@x=/(?=(\d\d))/g;print for @x"

Replies are listed 'Best First'.
Re^2: Global regexp
by throop (Chaplain) on Jun 16, 2008 at 12:32 UTC
    How would you modify that so that match only capture strings where the second digit is higher than the first? (Which is what I thought the OP meant, but I'm apparently wrong..) I'm scratching my head.

    throop

      In such cases, I mostly resort to enumeration:

      /(0[1-9] |1[2-9] |2[3-9] |3[4-9] |4[5-9] |5[6-9] |6[7-9] |7[8-9] |8[9-9])/

      will only capture pairs where the first digit is lower than the second digit. I'm not sure that there is a smarter/nicer version of that though ...

      It's usually best/simplest to just filter out the bad results.

      my @x; while (/(?=((\d)(\d)))/g) { push @x, $1 if $3 > $2; }

      You could also do that nicely using a lookup.

      my %ok; for my $i (1..8) { for my $j ($i+1..9) { $ok{"$i$j"} = 1; } } my @x = grep $ok{$_}, /(?=(\d\d))/g;

      You could build a complex pattern.

      use Regexp::List qw( ); my @ok; for my $i (1..8) { for my $j ($i+1..9) { push @ok, "$i$j"; } } my $re = Regexp::List->new()->list2re(@ok); my @x = /(?=($re))/g;

      In can be done programmatically in the regexp as well.

      my @x; push @x, $1 while /(?=((\d)(\d)(?(?{ $3 <= $2 })(?!))))/g;

      (It's pretty crazy that I was able to write the last one without errors and without checking perlre, so you probably shouldn't use that one.)

      All tested.

        push @x, $1 while /(?=((\d)(\d)(?(?{ $3 <= $2 })(?!))))/g;

        Bravo! That's the one I was looking for. I had a vague idea that it could be done within the regex, but I didn't know how to start.

        Of course, I had to study pelre for a half an hour to understand what you'd done. But I learned 3 or 4 new things about Perl on the way. The neat thing is, I'd looked at those parts of perlre before. But I couldn't make heads or tails of them without your example.

        Thanks!

        throop

Re^2: Global regexp
by Anonymous Monk on Jun 16, 2008 at 09:09 UTC
    Thank you.
    Actually, i read perlre doc, but i thought (?= ) wouldn't help me. So solution you gave looks for me like some perl hack :-)
      It does look a little bit hacky and I'm not sure you will find it explicitly discussed in either perlre or perlretut, but it is a kosher Perl regex expression and you need not worry about using it.