regex: single-digit backreferences \1..\9 (jolt-xtss)

\1..\9 now match the text captured by the corresponding group, so
patterns like ([-*_])\1\1 or (\w+) \1 work. The parser records which
groups are referenced; a referenced group additionally captures its text
under a tag and the backref compiles to a PEG (backmatch). Only referenced
groups change — they match possessively (the CPS-over-possessive-PEG engine
can't backtrack into a tagged capture), so backtracking back into a
backreferenced group isn't supported (rare). Unreferenced groups keep full
backtracking and position-based result capture unchanged.
This commit is contained in:
Yogthos 2026-06-16 23:49:15 -04:00
parent 91103fb52e
commit 39cb78a12d
2 changed files with 41 additions and 12 deletions

View file

@ -72,3 +72,12 @@
# expand to ~2^61 nodes and hang at compile time.
["nested bounds compile" "true"
"(boolean (re-matches #\"[a-z](?:[a-z]{0,61}[a-z])?(?:-[a-z]{0,61}[a-z])*\" \"abc-def\"))"])
(defspec "regex / backreferences (jolt-xtss)"
["repeated char" "true" "(boolean (re-find #\"(.)\\1\" \"abba\"))"]
["no repeat = nil" "nil" "(re-find #\"(.)\\1\" \"abc\")"]
["thematic-break run" "true" "(boolean (re-matches #\"([-*_])\\1\\1\" \"---\"))"]
["mismatched run" "nil" "(re-matches #\"([-*_])\\1\\1\" \"-*_\")"]
["repeated word" "[\"the the\" \"the\"]" "(re-find #\"(\\w+) \\1\" \"say the the word\")"]
["group still captures" "[\"x=x\" \"x\"]" "(re-matches #\"(\\w+)=\\1\" \"x=x\")"]
["html tag pair" "true" "(boolean (re-matches #\"<(\\w+)>.*</\\1>\" \"<b>hi</b>\"))"])