(?<name>...): named capture groups
(?<name>...) captures like an ordinary group and also files the result under a name, reachable as match.groups.name and as $<name> in a replacement string.
At a glance
- Syntax
- (?<name>...)
- Added in
- ES2018
- Access
- match.groups.name, and the group is still numbered as well
- Replacement token
- $<name>
- Name rules
- a valid identifier, unique within the pattern
- match.groups prototype
- null, so it has no inherited methods and no accidental key collisions
In detail
The value of a name is that it does not move. A numbered group depends on how many parentheses happen to appear before it, so reordering or wrapping part of a pattern silently repoints every later reference. A name is attached to the group itself and survives any amount of restructuring, which makes a long pattern far safer to edit.
Named groups are still numbered. The same group is available as m[1] and as m.groups.year, and a numbered backreference \1 works on it just as well as \k<year>. That means you can add names to an existing pattern without breaking anything that already reads it by number.
In a replacement string the token is $<name>. It sits alongside $1, $& and $$ in the same small language, and mixing named and numbered tokens in one replacement is legal if occasionally confusing. Reformatting a date reads considerably better as $<day>/$<month>/$<year> than as $3/$2/$1.
One detail worth knowing: match.groups is created with a null prototype, so it has no toString, no hasOwnProperty and no inherited anything. A group named constructor or toString therefore causes no collision, and a plain object spread of it is safe. It also means the usual object methods have to be called through Object.prototype rather than on the value.
Examples
const m = /(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/.exec("2026-03-08");
m.groups.y; // "2026"
m[1]; // "2026", named groups are numbered too
"2026-03-08".replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
"$<d>/$<m>/$<y>",
);
// "08/03/2026"const { groups: { y, m: month, d: day } } =
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/.exec("2026-03-08");
[y, month, day]; // ["2026", "03", "08"]Things that catch people out
- match.groups is undefined when the pattern has no named groups at all, so destructuring it without a guard throws on exactly the patterns you did not name.
- Group names must be valid identifiers and unique within the pattern. A duplicate name is a syntax error rather than a last one wins.
- In a replacement string the token is $<name>, not \k<name>. Using the backreference spelling there inserts the literal characters instead.
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 →\k<name>: backreferences to a named group
\k<name> repeats what a named group captured. Get the name wrong and, without the u flag, the escape quietly becomes a literal letter k.
(...) capturing groups: numbering and what comes back
How capture groups are numbered, what a group that did not participate returns, and why quantifying a group throws away everything but the last pass.
The d flag: capture group start and end offsets
What the d flag adds to a match result, how indices.groups mirrors named captures, and when the extra offsets are worth asking the engine for.
\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.
(?=...): 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.
Tools for this
- Regex Tester Free online regex tester - test and debug regular expressions with live matching and highlights
- AI Regex Explainer Get plain English explanations of regex patterns using a local AI - with live match testing
- Regex Playground Regex playground with live match highlighting, named groups, find and replace, and shareable links