Possessive Groups
As described in The Little Engine That /Could(n’t)?/, the Engine
often backtracks as it proceeds through the pattern. You
can block the Engine from backtracking back through a particular set of
choices by creating a nonbacktracking subpattern. A
possessive group looks like (?>, and
it works exactly like a simple noncapturing group PATTERN)(?:, except
that once PATTERN)PATTERN has found a match, it
suppresses backtracking on any of the quantifiers or alternatives inside
the subpattern. (Hence, it is meaningless to use this on a
PATTERN that doesn’t contain quantifiers or
alternatives.) The only way to get it to change its mind is to backtrack
to something before the subpattern and reenter the subpattern from the
left.
It’s like going into a car dealership. After a certain amount of haggling over the price, you deliver an ultimatum: “Here’s my best offer; take it or leave it.” If they don’t take it, you don’t go back to haggling again. Instead, you backtrack clear out the door. Maybe you go to another dealership and start haggling again. You’re allowed to haggle again, but only because you reentered the nonbacktracking pattern again in a different context.
For devotees of Prolog or SNOBOL, you can think of this as a scoped cut or fence operator.
Consider how in "aaab" =~
/(?:a*)ab/, the a* first
matches three as, but then gives up
one of them because the last a is needed later. The subgroup sacrifices some of what it wants in order for the whole match to succeed. (Which ...
Become an O’Reilly member and get unlimited access to this title plus top books and audiobooks from O’Reilly and nearly 200 top publishers, thousands of courses curated by job role, 150+ live events each month,
and much more.
Read now
Unlock full access