Learn Regex the Easy Way, Part 7: Capturing Groups and Backreferences

Quick Recap #

In Part 6, we learned about alternation with |, grouping with parentheses, and non-capturing groups (?:...). We saw that parentheses serve double duty: grouping for quantifiers and capturing matched text. Now let’s dig into the capturing side.

Parentheses Capture What They Match #

When you use regular parentheses (...), the engine saves whatever text matched inside them. The first set of parentheses is group 1, the second is group 2, and so on. The numbering goes left to right based on the opening parenthesis.

Backreferences: Matching the Same Text Again #

A backreference like \1 means “whatever group 1 actually matched.” Not the same pattern. The same text. This is a subtle but important distinction.

(                   # Group 1: capture a word
  [[:alpha:]]+      # One or more letters
)
[[:blank:]]         # A space
\1                  # Backreference: the SAME text group 1 matched

Compact: ([[:alpha:]]+) \1

MATCH THESE

  • the the
  • is is
  • hello hello

DO NOT MATCH THESE

  • the cat
  • is was
  • hello world

This is how you find duplicate words. The backreference \1 doesn’t mean “another word.” It means “the exact same word that was captured.”

Named Capture Groups #

Instead of numbering, you can name your groups. This makes complex regex much easier to read:

(?P<word>           # Named group "word"
  [[:alpha:]]+      # One or more letters
)
[[:blank:]]         # Space
(?P=word)           # Named backreference: same text

The syntax (?P<name>...) creates a named group, and (?P=name) references it.

Capture Groups in Find and Replace #

This is where capture groups become incredibly powerful. You capture something, then rearrange it in the replacement. The syntax varies by tool:

Practical Example: Reformatting Dates #

Convert MM/DD/YYYY to YYYY-MM-DD:

^
(                       # Group 1: Month
  [[:digit:]]{2}
)
/                       # Separator
(                       # Group 2: Day
  [[:digit:]]{2}
)
/                       # Separator
(                       # Group 3: Year
  [[:digit:]]{4}
)
$

Compact pattern: ^([[:digit:]]{2})/([[:digit:]]{2})/([[:digit:]]{4})$

Replacement: $3-$1-$2 (or \3-\1-\2 depending on the tool)

Input: 04/08/2026 becomes 2026-04-08

What to Practice #

  1. Write a regex that finds repeated words separated by a space. Test it on a paragraph with intentional duplicates.
  2. Write a find-and-replace regex that swaps first name and last name: “John Smith” becomes “Smith, John.”
  3. Write a regex with three named capture groups that parses a time in HH:MM:SS format.
  4. What does (.)\1 match? Think about it, then test it on regex101.

Definitions #


Series Navigation #

 
0
Kudos
 
0
Kudos

Now read this

Learn Regex the Easy Way, Part 3: Character Classes

Learn Regex the Easy Way, Part 3: Character Classes # Quick Recap # In Part 2, we learned about anchors and boundaries. The caret ^ matches the start of a line, $ matches the end, and \b matches word edges. They match positions, not... Continue →