CodeToolProCodeToolPro
GitHub
Testers·8 min read

Regex Tester Guide: Match, Capture Groups & Replace

CodeToolPro Team·

Regex Tester Guide: Match, Capture Groups & Replace

Regular expressions are the fastest way to find, extract, and rewrite text — once you can actually see what they match. A regex tester gives you a live view of matches, named groups, and replacements as you type, which is the difference between guessing and knowing.

Try every pattern below in our Regex Tester — it runs in your browser and shows matches instantly.

What a Regex Tester Does

At minimum it shows you three things:

  1. Matches — every span of text the pattern hits, highlighted in the sample.
  2. Groups — what each capture group (…) pulled out, including named groups.
  3. Replacement — the result of a replace operation using $1, $<name>, etc.

A good tester also flags syntax errors before you run the pattern, so you are not debugging a silent no-match.

Live Matching

Paste a sample (a log line, an email list, a code block) and type a pattern. The tester highlights every match:

Pattern: \b\d{3}-\d{4}\b
Sample:  Call 415-1234 or 555-9999 today
Matches: 415-1234, 555-9999

This is the fastest way to confirm a pattern before dropping it into code.

Capture Groups

Parentheses capture. Use them to pull structured fields out of messy text.

Pattern: (\d{4})-(\d{2})-(\d{2})
Sample:  2026-07-12
Group 1: 2026   (year)
Group 2: 07     (month)
Group 3: 12     (day)

Named groups make this readable:

(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})

Most testers render named groups alongside numbered ones.

Replacement

Reformat captured text with backreferences. In JavaScript/Python the syntax is $1 / \1 (or $<year> for named groups).

Pattern: (\d{4})-(\d{2})-(\d{2})
Replace: $3/$2/$1
Sample:  2026-07-12
Result:  12/07/2026

This is how you normalize dates, redact parts of a string, or reshuffle fields without writing a parser.

Flags

Flags change how a pattern behaves:

FlagNameEffect
gglobalmatch all occurrences, not just the first
iignore casea matches A
mmultiline^ and $ match line breaks, not just the whole string
sdotall. also matches newlines
uunicodetreat patterns as Unicode code points

A classic bug: forgetting g and wondering why only the first match is replaced.

Greedy vs Lazy

By default quantifiers are greedy — they grab as much as possible:

Pattern: <.*>
Sample:  <a>one</a> <b>two</b>
Match:   <a>one</a> <b>two</b>   ← the whole thing

Add ? to make it lazy (match as little as possible):

Pattern: <.*?>
Match:   <a>  and  <b>   ← separately

When parsing HTML or markup, lazy quantifiers usually give the result you wanted.

Backtracking Pitfalls

Catastrophic backtracking happens when a pattern like (a+)+$ is tested against aaaaaaaaaaaaaaaaaaaa!. The engine tries exponentially many ways to split the as, and the input can hang the thread. Avoid nested quantifiers on overlapping alternations, and prefer specific character classes over .+ where you can.

Common Patterns Cheat Sheet

Email:          [\w.+-]+@[\w-]+\.[\w.-]+
URL:            https?://[\w./?=&%-]+
IPv4:           \b\d{1,3}(\.\d{1,3}){3}\b
Date YYYY-MM-DD: \d{4}-\d{2}-\d{2}
Hex color:      #(?:[0-9a-fA-F]{3}){1,2}
Phone (US):     \(\d{3}\) \d{3}-\d{4}
Word boundary:  \b\w+\b

Code Examples

JavaScript

const re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/g;
for (const m of "2026-07-12".matchAll(re)) {
  console.log(m.groups); // { year: "2026", month: "07", day: "12" }
}

"2026-07-12".replace(/(\d{4})-(\d{2})-(\d{2})/, "$3/$2/$1");
// "12/07/2026"

Python

import re

m = re.search(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", "2026-07-12")
print(m.groupdict())  # {'year': '2026', 'month': '07', 'day': '12'}

re.sub(r"(\d{4})-(\d{2})-(\d{2})", r"\3/\2/\1", "2026-07-12")
# "12/07/2026"

Related Tools

When to Use a Tester Instead of Code

Any time you are writing a pattern you have not used before, prototype it in a tester against real samples first. It catches off-by-one groups, missing g flags, and greedy/lazy surprises in seconds — far cheaper than a failing unit test or a production regex that silently mismatches.