Regex Cheat Sheet: Patterns, Flags & Examples

September 26, 2026 · Web Development

A regular expression (regex) is a tiny language for describing text patterns: \d+ means "one or more digits", ^[a-z]+$ means "a whole string of lowercase letters". This cheat sheet covers the 20% of regex you'll use 95% of the time — with examples you can steal and the honest caveats most cheat sheets skip.

The essentials: literals, dot, and character classes

PatternMatchesExample
abcLiteral textabc matches "abc"
.Any character except newlinea.c matches "abc", "a_c"
\dAny digit (0–9)\d\d matches "42"
\wWord char: letters, digits, _\w+ matches "hello_1"
\sWhitespace (space, tab, newline)a\sb matches "a b"
[abc]Any one of a, b, c[aeiou] matches a vowel
[^abc]Anything except a, b, c[^0-9] matches non-digit
[a-z]Any char in the range[A-Za-z] any letter

Capital versions negate: \D is a non-digit, \W a non-word char, \S non-whitespace. Inside [...], most special characters lose their magic — [.] is a literal dot, no backslash needed.

Test as you learn: paste any pattern from this page into our free Regex Tester and watch matches highlight live, with capture groups broken out.

Quantifiers: how many?

PatternMeaningExample
*Zero or moreab*c matches "ac", "abc", "abbbc"
+One or more\d+ matches "7", "007"
?Zero or one (optional)colou?r matches "color", "colour"
{3}Exactly 3\d{3} matches "123"
{2,4}Between 2 and 4\w{2,4} matches "hi"–"test"
{2,}2 or morea{2,} matches "aa", "aaaa"

Greedy vs lazy is the classic confusion: quantifiers are greedy by default — they consume as much as possible. <.*> on <b>hi</b> matches the whole string, not just <b>. Add ? to make it lazy (match as little as possible): <.*?> matches <b> then </b> separately. When a pattern "matches too much", laziness is usually the fix.

Anchors and boundaries

PatternMeaning
^Start of string (or line with m flag)
$End of string (or line with m flag)
\bWord boundary

\bcat\b matches "cat" but not "concatenate" — the boundary sits between a word char and a non-word char. And remember: without ^...$ anchors, your pattern matches anywhere in the string. \d+ "validates" "abc123" as containing digits — which is rarely what validation means.

Groups, alternation, and backreferences

PatternMeaningExample
(abc)Group + capture(\d+)-(\d+) captures both number groups
(?:abc)Group without capturingFaster; use when you don't need the parts
a|bEither a or bcat|dog matches either word
(?<year>\d{4})Named groupRefer to it as "year" instead of group 1
\1Backreference to group 1(\w+)\s+\1 finds doubled words

Alternation has the lowest precedence: ^cat|dog$ means (^cat)|(dog$), not ^(cat|dog)$. When in doubt, add parentheses — explicit grouping beats precedence memorization.

Flags: the little letters that change everything

FlagNameEffect
gGlobalFind all matches, not just the first
iIgnore casecat matches "CAT"
mMultiline^/$ match line boundaries
sDot-all. matches newlines too

Copy-paste patterns that actually work

UsePatternHonest caveat
Email^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$Catches typos; not RFC-complete (good — see FAQ)
URLhttps?://[^\s/$.?#].[^\s]*Pragmatic; full URL validation is a rabbit hole
Date (YYYY-MM-DD)^\d{4}-\d{2}-\d{2}$Shape only — "2026-99-99" passes; validate ranges in code
Hex color^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$Covers #RGB and #RRGGBB
Slug^[a-z0-9]+(?:-[a-z0-9]+)*$Lowercase words joined by single hyphens
IPv4 (shape)^(?:\d{1,3}\.){3}\d{1,3}$Allows 999.999.999.999; range-check separately

Paste any of these into the Regex Tester with sample text — including text that should not match — before trusting them.

Three traps to memorize

  • Escaping in code strings: the string parser eats backslashes before regex sees them. In JavaScript "\\d" is fine in a regex literal /\d/ but needs doubling in new RegExp("\\d"). Python raw strings (r"\d") exist precisely for this.
  • Flavor differences: lookbehind, named groups, and Unicode property escapes (\p{L}) exist in modern JavaScript but not everywhere; Python's (?P<name>...) isn't JS syntax. Test in your deployment engine.
  • Catastrophic backtracking: nested quantifiers like (a+)+$ can hang on non-matching input. If a pattern ever freezes, this is almost always why — rewrite with more specific character classes.

Frequently asked questions

What is regex used for?
Validating input (emails, phone numbers), extracting structured bits from messy text (dates, IDs, prices from logs), and find-and-replace with patterns across codebases. If the task is "find text shaped like X", regex is usually the right tool.
What's the difference between * and +?
`*` means zero or more of the preceding element; `+` means one or more. So `\d*` matches an empty string (it's happy with zero digits), while `\d+` requires at least one digit. This is the single most common source of "why did it match nothing?" bugs.
How do I validate an email with regex?
Use a pragmatic pattern like `^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$` — it catches typos and malformed input. Don't chase a "perfect" email regex; the RFC allows bizarre addresses no regex should try to bless. Validate shape with regex, verify ownership by sending an email.
What do ^ and $ do?
`^` anchors a match to the start of the string (or line, with the multiline flag) and `$` anchors to the end. `^\d+$` means "the entire string is digits" — without anchors, `\d+` happily matches the digits inside "abc123".
Why isn't my regex matching across newlines?
Two usual causes: the dot `.` doesn't match newlines by default (enable the dot-all flag `s`), or `^`/`$` are matching string boundaries instead of line boundaries (enable multiline `m`). Check which one your pattern actually needs.
Are regex flavors different?
Yes — JavaScript, Python, PCRE (PHP), Go, and Java each support a different feature set. Named-group syntax, lookbehind support, and inline flags all vary. Always test in the engine you'll deploy, not just the one you learned in.
How do I escape special characters?
Prefix with a backslash: `\.` for a literal dot, `\$`, `\(`, etc. Inside a character class `[...]` most specials lose their meaning, but `]`, `\`, `^` (first), and `-` (between chars) still need care. In code strings, remember the string itself may eat a backslash first — `"\\d"` in many languages is the regex `\d`.

Related articles

Try the free tool