\k<name>: backreferences to a named group
\k<name> matches the text captured by the named group with that name. It only behaves as a backreference when the pattern actually defines the name.
At a glance
- Syntax
- \k<name>
- Requires
- a group with that exact name in the same pattern
- Added in
- ES2018, alongside named groups
- Name not defined, no u flag
- \k becomes a literal k and the pattern silently changes meaning
- Name not defined, with u flag
- SyntaxError, invalid named capture
- In a replacement string
- $<name>, not \k<name>
In detail
As a backreference it behaves exactly like \1, matching the text the group captured rather than re-running its pattern. The gain is the same as for named groups generally: the reference does not break when parentheses are added elsewhere, and it says what it means, which matters most in the long patterns where backreferences appear.
The failure mode is the interesting part. If the pattern has no group with that name and the u flag is not set, the legacy compatibility rules turn \k into a plain letter k. The pattern still compiles, and /\k<x>/ ends up matching the literal five character text k<x>. Nothing anywhere reports a problem.
Turning on u converts that into a SyntaxError about an invalid named capture, which is exactly the behaviour you want from a typo. Compiling suspect patterns with u once is a cheap way to find every mistyped group name in a codebase, even if you then run them without the flag.
Named and numbered references can be mixed freely, because a named group is also numbered. \1 and \k<word> pointing at the same group are both valid, and in a replacement string the corresponding tokens are $1 and $<word>. What you cannot do is use \k<name> in a replacement string; that spelling only exists inside the pattern.
Examples
const dup = /(?<word>\b\w+\b)\s+\k<word>/;
dup.test("the the cat"); // true
dup.exec("the the cat")[0]; // "the the"
"<b>hi</b>".match(/<(?<t>[a-z]+)>.*?<\/\k<t>>/)[0]; // "<b>hi</b>"/\k<x>/.test("k<x>"); // true, the pattern is literal text
new RegExp("\\k<x>", "u"); // SyntaxError: Invalid named capture referencedThings that catch people out
- A misspelled group name is not an error without the u flag. The escape becomes a literal k and the pattern searches for the name you typed instead.
- \k<name> has no meaning in a replacement string. The token there is $<name>, and the backreference spelling inserts the characters verbatim.
- The angle brackets are part of the syntax. Writing \kname is a literal k followed by the word, with no warning that a backreference was intended.
Try it: Regex Tester
Type a pattern and a test string, watch every match highlight as you go, read a plain English breakdown of each token, and check the numbered and named groups it captured.
Regex Tester
LOCAL · Browser-OnlyTest and debug regular expressions with live matching and highlights
Related Regex syntax
All regex syntax →(?<name>...): named capture groups
Named groups survive being reordered, read as documentation and give you $<name> in replacements. They are still numbered underneath.
\1: backreferences that match what a group captured
A backreference matches the exact text a group captured, not the pattern that captured it. Inside a character class the same escape means something else.
The u flag: Unicode mode
What the u flag changes about how a pattern is parsed, the escape forms it unlocks, and the previously tolerated syntax it turns into a hard error.
(?=...): positive lookahead for zero width tests
A lookahead asserts what comes next without consuming it, which is how several independent rules can all be checked from the same position.
(?!...): negative lookahead for exclusion rules
A negative lookahead succeeds when the pattern inside it fails. The classic bug is a greedy quantifier that backtracks until the assertion passes.
(?<=...): positive lookbehind and where it runs
JavaScript allows variable length lookbehind, which Java does not, and matches its contents from right to left. RE2 based engines have none at all.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links