Regex Groups, Backreferences & Lookarounds
Once you're past character classes and quantifiers, groups and assertions are what make regex genuinely powerful — extracting parts of a match, matching repeats, and matching based on context. Here's how they work.
This is a supporting guide in The Complete Guide to Regular Expressions.
Capturing groups
Parentheses do two things: they group part of a pattern so a quantifier or alternation applies to the whole thing, and they capture what matched so you can pull it out afterward.
(\d{4})-(\d{2})-(\d{2}) on 2026-08-28
group 1 = 2026 group 2 = 08 group 3 = 28
Groups are numbered left to right by their opening parenthesis. In a replacement, you refer back to them with $1, $2, … — so replacing with $3/$2/$1 turns the date into 28/08/2026.
Named groups
Numbered groups get hard to track. Named groups give them labels: (?<year>\d{4}) captures into a name you reference as year (or $<year> in a replacement). Clearer, and stable if you reorder the pattern.
Non-capturing groups and alternation
Sometimes you want to group without capturing — to apply a quantifier or an alternation. Use (?:...):
(?:ab)+— one or more "ab", but not captured(cat|dog|fish)— alternation: any one of the three (captured)(?:https?|ftp)://— group the scheme options without a capture slot
Backreferences
A backreference matches the same text a previous group captured. (["']) followed by \1 matches a matching pair of quotes:
(["']).*?\1 matches "hello" and 'hi'
but not "mismatched'
\1 refers to whatever group 1 actually captured, so the closing quote must be the same character as the opening one.
Lookahead and lookbehind
Lookarounds assert that something does (or doesn't) come next, without consuming it — the match position doesn't move past the asserted text:
foo(?=bar)— "foo" only if followed by "bar" (positive lookahead)foo(?!bar)— "foo" only if not followed by "bar" (negative lookahead)(?<=\$)\d+— digits only if preceded by "$" (positive lookbehind)(?<!\$)\d+— digits not preceded by "$" (negative lookbehind)
A common use: (?=.*\d)(?=.*[a-z]) as password rules — assert a digit exists and a lowercase letter exists, without those assertions consuming any characters.
Related
Part of The Complete Guide to Regular Expressions. See also Character Classes, Quantifiers & Anchors.
Try it
Build a pattern with groups and lookarounds in the Regex Tester and watch each capture group appear as you type — all in your browser.