Find and Replace Text Using Regex Capture Groups
Reformatting a batch of text by hand, moving a date from one order to another or stripping a prefix off a hundred log lines, is slow and error-prone the moment the batch grows past a handful of lines. A capture group turns each matched piece of a pattern into a reusable reference, and Replace mode lets you rearrange those references into a new shape while watching the exact result update as you type.
What a capture group actually captures
Parentheses inside a pattern do two things at once: they group part of the pattern together, and they capture whatever text matched that part so it can be referenced later.1 A pattern like (\d{4})-(\d{2})-(\d{2}) matched against 2026-08-13 captures three separate pieces, the year, the month, and the day, each addressable on its own even though the whole match is one contiguous string.
Named groups add a second way to reference the same captured text. Writing (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2}) instead captures the identical three pieces but lets the replacement template refer to them by name rather than by position, which matters once a pattern has enough groups that counting parentheses to find "group 3" becomes error-prone.1
Confirming which text landed in which group before replacing anything
Before writing a replacement template, checking Match mode's group inspector confirms each numbered or named group actually captured what you expect. If group 2 is supposed to hold the month but the inspector shows a two-digit year fragment instead, the parentheses are in the wrong place, and fixing that before switching to Replace mode saves a confusing round of debugging a replacement that looked right but used the wrong source text.
The inspector lists every group's exact character range alongside its captured text, which matters once two groups capture strings that happen to look similar, like a two-digit month next to a two-digit day. Confirming the range rather than just eyeballing the captured digits removes any ambiguity about which group is which before that ambiguity turns into a swapped field in your replacement output.
Writing a replacement template that rearranges the pieces
Replace mode's template field follows the same syntax JavaScript's own String.replace uses, so whatever produces the right result here produces the identical result in your actual code. $1 through $9 insert numbered capture groups by position, $<name> inserts a named group by its label, $& repeats the entire match, and $$ inserts a literal dollar sign when your output genuinely needs one.2
Reformatting the date example from before means writing $3/$2/$1 for the numbered version or $<day>/$<month>/$<year> for the named version, and both produce 13/08/2026 from the same input. The live preview beneath the replacement field updates on every keystroke, so a swapped group order or a missing slash shows up immediately rather than after you have already copied the wrong output somewhere else.
Catching an off-by-one group reference before it ships
The most common replacement mistake is referencing the wrong group number after inserting or removing a group earlier in the pattern, since every group after the change shifts position by one. Watching the live preview while you edit the pattern itself, not just the replacement template, catches that shift the moment it happens instead of after the output silently starts producing the wrong field in the wrong place.
Deciding when a replacement should run once or everywhere
The Global flag controls how many matches a replacement touches, and getting this wrong produces two very different kinds of bug. With the flag off, only the first match in your test text gets replaced, which is correct when you are editing one specific occurrence but silently wrong the moment your real input contains more than one match you meant to catch.3
Choosing Global for a batch instead of one edit
Toggling Global on rewrites every match in the text at once, using the same template against each one independently. For a batch of log lines that all share the same date format, that difference is the entire point of using a pattern-based replace instead of a manual find-and-replace in a text editor: one template, applied consistently, across every line that matches.
Watching the live preview while toggling Global on and off against the same test text is a fast way to confirm which behavior your actual task needs before you copy the result anywhere. A preview that changes length dramatically the moment you toggle the flag is a clear sign your original test text held more matches than you had accounted for.
When to use this
Use this guide any time you need to reformat matched text using capture-group references in Replace mode, whether by numbered groups or named groups.
Examples
Reformatting a date using numbered capture groups
Pattern: (\d{4})-(\d{2})-(\d{2})
Replacement: $3/$2/$1
Test text: 2026-08-13 The live preview shows 13/08/2026, with each numbered group inserted in its new position.
The same reformat using named capture groups
Pattern: (?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})
Replacement: $<day>/$<month>/$<year>
Test text: 2026-08-13 The live preview again shows 13/08/2026, but the replacement template reads by name instead of by position.
Named and numbered groups capture the same text; only the way you reference them in the replacement differs.
- 1.
MDN Web Docs, "Named capturing group: (?<name>...)," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Regular_expressions/Named_capturing_group
- 2.
Jan Goyvaerts, "Reinserting Text Matched By Capturing Groups in The Replacement Text," regular-expressions.info, accessed August 2026. https://www.regular-expressions.info/replacebackref.html
- 3.
MDN Web Docs, "RegExp.prototype.global," developer.mozilla.org, accessed August 2026. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/global