(?R), (?1), (?&name), \g<0> — call the pattern again¶
One line: A subroutine call re-runs a group's pattern at this position (a backreference re-matches its text), and (?R) re-runs the whole pattern, which is what it takes to match balanced parentheses; Perl and PCRE2 spell it (?R) / (?1) / (?&name), Ruby spells it \g<0> / \g<1> / \g<name>, the two dialects have no overlap, and two other engines accept one of the spellings while meaning something else.
Level: reference · one construct, eight engines — the lesson has the depth
What it means¶
| Construct | Perl / PCRE2 / ABAP | Ruby (Onigmo) |
|---|---|---|
| Recurse into the whole pattern | (?R), (?0) |
\g<0> |
| Call group 1's pattern | (?1) |
\g<1> |
| Call a named group's pattern | (?&name), (?P>name) |
\g<name> |
| Relative call | (?-1), (?+1) |
\g<-1>, \g<+1> |
Python re, JavaScript, Java, Go and Rust's regex have none of this. fancy-regex has none of it either. The Python third-party regex module has the PCRE spelling.
Measured¶
Verified output of kw_recursion_and_subroutine_calls_sh.sh — regenerated by tools/run_examples.py, never hand-typed.
construct python perl node ruby java go rust fancy
(?R) whole pattern - (a(b)c) - - - - (b) -
(?1) group one - (a(b)c) - - - - - -
(?&name) - (a(b)c) - - - - - -
\g<0> Ruby spelling - - (b) (a(b)c) - - - -
\g<name> Ruby spelling - - (b) (a(b)c) - - - -
subroutine vs backref - 12-34 - - - - - -
backref for comparison no no no no no - - no
Reading the table¶
- Rows 1–3, the PCRE dialect.
(?R),(?1)and(?&name)each match the whole of(a(b)c)in Perl. Ruby, Python, JavaScript, Java, Go andfancy-regexrefuse all three. - Row 1, Rust.
regexdid not refuse(?R).Ris its CRLF-mode flag, so(?R)is a flag group that consumes nothing, the pattern collapses to one level of parentheses, and the first match is the inner(b). It compiles, it matches, it is not recursion. - Rows 4–5, the Ruby dialect.
\g<0>and\g<name>match the whole nested subject in Ruby, and are refused by Perl — the dialects do not overlap in either direction. JavaScript did not refuse them:\gis an identity escape, so\g<0>is the literal textg<0>and the alternative[^()]|g<0>matches(b). The library's engines table once said recursion was Perl's alone, because its probe only asked for(?R). - Rows 6–7, call versus backreference.
(\d\d)-(?1)matches12-34in Perl: the second\d\dis the pattern again.(\d\d)-\1matches nothing, in every engine that has backreferences:\1wants the text12again. That line — pattern versus text — is the whole difference between this page and backreference.
The trap¶
Two engines compiling one of the spellings and meaning something else: Rust for (?R), JavaScript for \g<…>. A compile-only probe credits both with recursion. The lesson's own probe asked "does it match the nested subject" for exactly this reason.
The judgement call, from the lesson: nested structure usually wants a parser. A dozen lines of depth-counting in the host language handles unbalanced input and unlimited depth, is portable to every engine on this page, and is what Go and Rust force on you anyway. The recursive pattern is a real capability where it exists — and on hostile input it is catastrophic backtracking again.
Where it is measured in depth¶
- Matching nested structures — six spellings × five engines, the anchor trap, depth to 1000, the counter in Python, and the ABAP source.
See also¶
- Backreference — text, not pattern.
- Conditional —
(?(DEFINE)…)for naming the sub-patterns a call refers to;(?(R)…)for "am I inside a recursion". - Forward references — the page that first draws the four-names distinction.