Why is Perl lazy when regex matching with * against a group?

perl, regex

Solution

This isn't a matter of greedy or lazy repetition. `(?:fj)*` is greedily matching as many repetitions of "fj" as it can, but it will successfully match zero repetitions. When you try to match it against the string `"f fjfj ff"`, it will first attempt to match at position zero (before the first "f"). The maximum number of times you can successfully match "fj" at position zero is zero, so the pattern successfully matches the empty string. Since the pattern successfully matched at position zero, we're done, and the engine has no reason to try a match at a later position.

The moral of the story is: don't write a pattern that can match nothing, unless you want it to match nothing.

Problem

In perl, the `*` is usually greedy, unless you add a `?` after it. When `*` is used against a group, however, the situation seems different. My question is "why". Consider this example: ``` my $text = 'f fjfj ff'; my (@matches) = $text =~ m/((?:fj)*)/; print "@matches\n"; # --> "" @matches = $text =~ m/((?:fj)+)/; print "@matches\n"; # --> "fjfj" ``` In the first match, perl lazily prints out nothing, though it could have matched something, as is demonstrated in the second match. Oddly, the behavior of `*` is greedy as expected when the contents of the group is just `.` instead of actual characters: ``` @matches = $text =~ m/((?:..)*)/; print "@matches\n"; # --> 'f fjfj f' ``` - Note: The above was tested on perl 5.12. - Note: It doesn't matter whether I use capturing or non-capturing parentheses for inside group.

Original source