All posts

Find and Replace with Regex: A No-Nonsense Cheat Sheet

The regex patterns that pay for themselves: emails, phone numbers, whitespace cleanup, capture groups and the difference between greedy and lazy matching.

June 25, 2026 7 min read

Regex earns its reputation for being unreadable. But the 90% of patterns you actually need fit on one page. Bookmark this; you'll come back to it.

The Building Blocks

  • . — any character except newline
  • \d — digit · \D — non-digit
  • \w — word char (a–z, A–Z, 0–9, _) · \W — non-word
  • \s — whitespace · \S — non-whitespace
  • ^ — start of line · $ — end of line
  • [abc] — any of a, b, c · [^abc] — none of a, b, c
  • [a-z] — range

Quantifiers

  • * — 0 or more · + — 1 or more · ? — 0 or 1
  • {3} — exactly 3 · {2,5} — 2 to 5 · {2,} — 2 or more
  • Add ? after any quantifier to make it lazy: .*?

Greedy vs Lazy — The One That Bites Everyone

Greedy <.*> on the text <b>hi</b> matches the whole string. Lazy <.*?> matches just <b>. Use lazy whenever you're pulling content out from between two delimiters.

Capture Groups & Backreferences

Wrap part of a pattern in (...) to capture it. Reference it in your replacement with $1, $2, etc. To swap "Lastname, Firstname" into "Firstname Lastname":

Find:    (\w+), (\w+)
Replace: $2 $1

Patterns That Pay for Themselves

  • Trim extra spaces: {2,} → single space
  • Strip blank lines: ^\s*$\n → empty
  • Email-ish match: [\w.+-]+@[\w-]+\.[\w.-]+
  • Phone digits only: \D → empty (keep only digits)
  • Markdown bold to HTML: \*\*(.+?)\*\*<strong>$1</strong>

Test Before You Replace

Regex replace is destructive. Always test the pattern on a small sample, look at the matches, then run it on your full text. A misplaced .* can eat a whole document.

Frequently Asked Questions

Related reads