Text Tools

Regex Find and Replace: Capture Groups and $1, $2 References Explained

What a Capture Group Does

Wrapping part of a regex pattern in parentheses (...) creates a capture group — it doesn't just match that part of the text, it remembers what specifically matched, so you can reuse it in the replacement. Groups are numbered automatically, left to right, starting from 1.

A Worked Example: Reformatting a Date

"2024-09-27".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1")
// Result: "27/09/2024"

The pattern captures three groups — the year, month, and day — and the replacement string rearranges them using $1, $2, and $3 to reference each captured group by its position, converting the date from year-first to day-first format.

Named Groups for Readability

"John Smith".replace(/(?<first>\w+) (?<last>\w+)/, "$<last>, $<first>")
// Result: "Smith, John"

Instead of tracking numeric positions, a named group — (?<name>pattern) — lets you reference it by a descriptive name in the replacement using $<name>, which stays readable even in a pattern with many groups.

Non-Capturing Groups

Sometimes you need parentheses purely to group part of a pattern — without needing to reference that specific piece in the replacement. (?:pattern) groups without capturing, and doesn't consume a group number, keeping your numbered references clean if you have other groups you do want to reference.

A Cross-Language Gotcha

JavaScript uses $1, $2 in replacement strings. Python and PHP use \1, \2 instead. Copying a pattern from one language's documentation or examples into a JavaScript-based tool without converting the reference syntax is a common, easy-to-make mistake — the replacement ends up inserting the literal text \1 rather than the captured content.

Ready to try capture groups yourself?

Open Find and Replace Tool