Regex basics for developers: patterns that actually matter

8 min readUpdated May 24, 2026

Regular expressions look like line noise until they click. This guide covers the building blocks you will use 90% of the time — and you can try every pattern live in the regex tester.

Character classes

  • . — any character except newline.
  • \d / \D — a digit / a non-digit.
  • \w / \W — a word character ([A-Za-z0-9_]) / non-word.
  • \s / \S — whitespace / non-whitespace.
  • [abc] — any one of a, b, c. [^abc] — anything but those. [a-z] — a range.

Quantifiers

  • * — zero or more. + — one or more. ? — zero or one (optional).
  • {3} — exactly 3. {2,5} — 2 to 5. {2,} — 2 or more.
  • Add ? to make any quantifier lazy (match as little as possible): .*?

Greedy vs lazy matters: <.*> on <a><b> matches the whole string; <.*?> matches just <a>.

Anchors and boundaries

^ matches the start of input (or line, in multiline mode), $ the end. \b matches a word boundary — essential for whole-word matches.

\bcat\b   // matches "cat" but not "category"

Groups and capturing

  • ( ) — a capturing group you can reference as $1, $2 in replacements.
  • (?: ) — a non-capturing group, for grouping without capturing.
  • (?<name> ) — a named group, referenced as $<name>.
  • (a|b) — alternation: a or b.

Build and debug your pattern against real input in the Regex Tester — it highlights matches and shows capture groups as you type.

Patterns to copy

\d{4}-\d{2}-\d{2}            // ISO-ish date
[\w.+-]+@[\w-]+\.[\w.-]+     // rough email
https?:\/\/[^\s]+            // URL
^\s*$                        // blank line
Regex is great for structured text but a poor fit for nested formats like HTML or JSON — use a real parser for those.

Frequently asked questions

What is the difference between greedy and lazy matching?
Greedy quantifiers (*, +) match as much as possible; adding ? makes them lazy, matching as little as possible. This changes results dramatically on repeated patterns.
Why should I not parse HTML with regex?
HTML is nested and irregular; regex cannot reliably handle arbitrary nesting. Use a DOM parser instead. Regex is fine for simple, flat text patterns.
How do I match a whole word only?
Wrap it in word boundaries: \bword\b. This prevents matching the substring inside a larger word.
What are capture groups for?
Parentheses capture part of a match so you can extract or reuse it — for example reordering date parts in a replacement using $1, $2.

Try it yourself

Put this guide into practice — these tools run free in your browser.