Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

How can regex range quantifier { } as a greedy one, not one e.g: <br/?
'aaabb' =~ /aa(b(?{print "\nYes b letter"})){0,2}/ will give nothing

Please solve get greedy not lazy one

Replies are listed 'Best First'.
Re: Must do regex range quantifier { } as a greedy
by LanX (Saint) on Jan 17, 2022 at 08:35 UTC
    That's what you want?

    DB<21> say 'aaabbbb' =~ /aa(?!a)b{0,2}/; say "<$&>" 1 <aabb>

    Ranges are greedy by default, i.e. if they match at all.

    BUT

    DB<22> say 'aaaccccaaabbbb' =~ /aa(?!a)b{0,2}/; say "<$&>" 1 <aa>

    Please elaborate...

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Your elegant solution won't match the edge case of aa, but it's unclear to me whether that is relevant for the OP.

        > won't match the edge case of aa

        hmm ... works for me

        DB<24> say 'aa' =~ /aa(?!a)b{0,2}/; say "<$&>" 1 <aa>

        or did you mean something else?

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery

Re: Must do regex range quantifier { } as a greedy
by Corion (Patriarch) on Jan 17, 2022 at 08:39 UTC

    Using Regexp::Debugger, you can see that the regexp immediately matches at the start of the string, because aa (followed by zero b) matches.

    If you want to match the aab, you can push the match to the right by preprending .*:

    "aaabb" =~ /.*aa(b(?{{print "\nYes b letter"}})){0,2}/
      Your elegant solution will match the rightmost case of "aab+" not the longest, but it's unclear to me whether that is relevant for the OP. ;-)
Re: Must do regex range quantifier { } as a greedy
by ikegami (Patriarch) on Jan 18, 2022 at 04:53 UTC

    It is greedy.

    b{0,2} can't magically skip ahead to match characters in a different location in the string; it's constrained to matching at the current position. With that in mind, the match operation matches an a at position 0, then an a at position 1, then zero b at position 2. It wants to match two of them (since it's greedy), but there aren't any to match at position 2! So it settles for matching zero (which you allowed it to do).

    It doesn't match one b as you claim.


    Note that your usage of (?{ }) won't work in general. Consider the following:

    "abdabbc" =~ /a(?:b(?{ say "b"; }))+c/

    This prints three b even though the pattern only matches two. To get the correct count, you need

    "abdabbc" =~ /a(?:b(?{ local $c = $c + 1; }))+c(?{ say $c; })/
Re: Must do regex range quantifier { } as a greedy
by Anonymous Monk on Jan 17, 2022 at 11:47 UTC
      The relevant part is rather

      By default, a quantified subpattern is "greedy", that is, it will match as many times as possible (given a particular starting location) while still allowing the rest of the pattern to match. If you want it to match the minimum number of times possible, follow the quantifier with a "?"

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery