Skip to content

Chapter 4 of 8

Groups, Captures, and Backreferences

Parentheses do three distinct things in regex, and a good pattern keeps them straight. A capturing group, written (...), records the text it matches so it can be referenced later. Groups are numbered left to right starting at 1, so in (\d{4})-(\d{2}) the first group captures the year and the second captures the month. Captures are powerful: they let you pull structured data out of unstructured strings, and they are the foundation of replacement operations that rearrange text. A non-capturing group, written (?:...), groups tokens for quantifiers or alternation without recording the match, which is the right choice whenever you do not need the captured text. Use non-capturing groups by default to keep numbering predictable and to give the engine slightly less work.

Named capturing groups give meaningful handles to captures. In most flavors the syntax is (?<name>...), with the older Python form (?P<name>...) still supported. You access the captured text by name in code through group("name"), and inside the pattern itself with a backreference like \k<name>. Named groups shine when a pattern has many captures or when the order of groups may change as the pattern evolves. The alternation operator | lets a pattern choose between alternatives at the same position, as in cat|dog. To control precedence or to apply a quantifier to a whole alternative, wrap the alternatives in a group: (?:cat|dog)s? matches cat, cats, dog, or dogs.

A backreference refers to text previously captured by a numbered or named group, and it is one of the most expressive features of regex. The pattern ([abc])\1 matches aa, bb, or cc because \1 requires the next character to be identical to whatever the first group captured. In replacement strings the syntax differs by tool: Perl and JavaScript use $1, while sed and the regex body itself use \1. Backreferences enable patterns that would otherwise require manual parser code, such as \b(\w+)\s+\1\b for finding doubled words or <(\w+)>.*?</\1> for matching balanced HTML open and close tags. Note that backreferences force the engine to be NFA-based, so a regex with them cannot be compiled to a pure DFA.

All chapters
  1. 1Character Matching: Metacharacters, Shorthands, and Classes
  2. 2Quantifiers: Greedy, Lazy, Possessive, and Exact
  3. 3Anchors and Boundaries
  4. 4Groups, Captures, and Backreferences
  5. 5Lookaround Assertions
  6. 6Flags, Modes, and Engine Features
  7. 7Practical Recipes for Validation and Extraction
  8. 8Performance and Engine Internals

Drill it

Reading is not remembering. These come from the Regex Patterns Every Developer Should Know deck:

Q

What does the regex metacharacter <code>.</code> match by default?

A single character of any kind except the newline character (\n). To make it also match newlines, use the s (dotall / single-line) flag, e.g. /foo.bar/s in Java...

Q

Which character class matches any single digit in most regex flavors?

[0-9] or the shorthand \d. \d is equivalent to [0-9] in ASCII; with Unicode (u flag in JS, default in Python 3 str) it matches any Unicode decimal digit, e.g. A...

Q

What does the shorthand <code>\w</code> match?

Any word character. In ASCII mode this is [A-Za-z0-9_]; in Unicode mode it also matches letters and digits from other scripts, and the underscore.

Q

What does the shorthand <code>\s</code> match?

Any whitespace character: space, tab (\t), newline (\n), carriage return (\r), form feed (\f), and vertical tab (\v). In Unicode mode it can also match rare whi...