DevLab
.*
Regexintermediate

Named Capture Groups

learn and test named capture groups in regex

By Bikram NathLast updated

Named capture groups label regex submatches with string keys so you access `match.groups.year` instead of `match[2]`. Apply `(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})` to "2026-05-19" and you get `{year: "2026", month: "05", day: "19"}` back. The tool shows the resulting groups object live and compares JavaScript and Python named-group syntax in the same view, which no single engine REPL does.

Try it now — free, instant, no signup

What is Named Capture Groups?

Named capture groups extend standard regex submatches by binding a string label to each group. Where a conventional pattern returns `match[2]` for a month field, `(?<month>\d{2})` gives back `match.groups.month`, self-documenting at the call site. The tool lets you write a pattern and immediately see the named groups object it produces against sample text you paste in, with output shown for JavaScript and Python in parallel.

Most developers reach for regex101 when debugging a pattern, and it is the right choice for flag exploration and step-by-step match highlighting. This tool fills a narrower gap: it surfaces the difference between JavaScript's `(?<name>...)` form, which landed in ECMAScript 2018 via V8 6.0, and Python's `(?P<name>...)` form side-by-side, which regex101 does not present in a diff view. If you already know which engine you are targeting, regex101 wins on depth; if you are writing a cross-language pattern, the side-by-side view saves a round-trip.

The most common gotcha is duplicate group names. JavaScript runtimes before ECMAScript 2025 (Node.js under 22, Chrome under 125) throw a SyntaxError if the same name appears even inside alternation branches. ECMAScript 2025 legalized `(?<x>a)|(?<x>b)` for alternation-only cases. Python's `re` module allowed the same name in alternation since 3.7 but still rejects it outside alternation positions, so the two engines diverge in edge cases most developers do not hit until production.

When to use Named Capture Groups

Migrate a numbered-group pattern to named groups so teammates can read extracted fields without counting parentheses.
Verify that a shared regex pattern compiles and extracts correctly under both JavaScript and Python before committing.
Debug a log parser returning wrong fields after the log format gains a column and shifts every positional index.

Frequently Asked Questions

Does Python use different named-group syntax than JavaScript?
Yes. Python's `re` and `regex` modules use `(?P<name>...)`, and the `P` is required. JavaScript (ECMAScript 2018+) and most PCRE-based engines use `(?<name>...)` without the `P`. If you copy a Python pattern into a JavaScript engine, the `P` causes a SyntaxError. Going the other direction, bare `(?<name>...)` works in Python's third-party `regex` module but not in the standard `re` module on Python versions before 3.7.
Can I reference a named group inside the replacement string?
In JavaScript, `String.prototype.replace` accepts `$<name>` in the replacement string. For example, `'2026-05-19'.replace(/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/, '$<d>/$<m>/$<y>')` returns `'19/05/2026'`. In Python, `re.sub` uses `\g<name>` in the replacement template. The two syntaxes are not interchangeable, so if your replacement string must run in both environments you need two separate template strings, one per engine.
What actually happens when the same group name appears twice in one pattern?
In JavaScript before ECMAScript 2025 (Node.js under 22, Chrome under 125), a duplicate named group throws a SyntaxError at pattern compile time, not at match time. ECMAScript 2025 legalized `(?<x>a)|(?<x>b)` for alternation branches only. Python's `re` module permits the same name inside alternation since 3.7 but raises `re.error` if the name repeats in non-alternating positions. In either engine only one branch can match, so `match.groups.x` returns whichever branch succeeded.
Why does `match.groups` return `undefined` even though my pattern compiles fine?
The `groups` property on a JavaScript `RegExp` match result was added in ECMAScript 2018. Node.js 8 and earlier, and browsers predating Chrome 64 or Firefox 78, return `undefined` for `match.groups` even when the pattern itself compiles without error. If you are on a modern runtime and still see `undefined`, confirm you are reading `match.groups` (plural), as there is no singular `match.group` form in JavaScript the way Python exposes `match.group('name')`.
Can named capture groups be defined inside a lookahead or lookbehind?
Yes, with one important caveat. You can define a named group inside a positive lookahead and JavaScript will populate it if the assertion succeeds. Lookbehind support is the limiting factor: ECMAScript 2018 added lookbehinds to V8, but Safari shipped lookbehind support only in Safari 16.4 released in 2023. If your regex runs in a browser and requires named groups nested inside a lookbehind, you need to verify the minimum Safari version you support before shipping that pattern.

Related Tools