Recursive Patterns
When you reference a capture group from within the pattern, whatever was actually captured by that group is what gets used for the backreference.
/\b ( \p{alpha}+ ) \s+ \1 \b /x # numbered backref
/\b ( \p{alpha}+ ) \s+ \g{1} \b /x # alternate syntax
/\b ( \p{alpha}+ ) \s+ \g{–1} \b /x # relative backref
/\b (?<word> \p{alpha}+ ) \s+ \k<word> \b /x # named backrefThose four examples all use backreferences to match the same word twice in a row. But sometimes you want to match two different words with the same pattern.
For that, a different syntax is used: (? calls
back into the pattern of a numbered group, whereas NUMBER)(?& does
so for a named group. (The latter is reminiscent of the NAME)& form of subroutine calls.)
/\b ( \p{alpha}+ ) \s+ (?–1) \b /x # "call" numbered group
/\b (?<word> \p{alpha}+ ) \s+ (?&word) \b /x # "call" named groupWith the NUMBER form, a leading minus
sign counts groups right to left from the current location, so –1 means to call the previous group; you don’t
have to know the absolute position of it. On the other hand, if the
number has a plus sign in front, (?+, you
count forward that many groups to the right of where you are.NUMBER)
You are even allowed to call a group that you’re already in the middle of, causing the matching engine to recurse on itself. This is a normal thing to want to do. Here’s one way to match balanced parentheses:
/ ( \( (?: [^()]++ | (?1) )*+ \) )/x
Because the entire pattern is enclosed by capture parentheses, you ...
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