Forgot what \b means halfway through writing a regex? Or wrote one that looks right but doesn’t match anything when run? This guide gives you a practical cheat sheet — organized into 4 sections: metacharacters, quantifiers, groups, and real examples, each with a plain-language explanation. Use it with the Piick regex tester to look up and test as you go.

Metacharacter cheat sheet

All the special symbols in regex that aren’t literal characters are called metacharacters. The 12 most common:

  • . any single character (doesn’t match newlines by default; needs the s flag to match them)
  • ^ start of line (matches each line’s start in multiline mode)
  • $ end of line (matches each line’s end in multiline mode)
  • \b word boundary (between a word character \w and a non-\w)
  • \d digit, equivalent to [0-9]
  • \D non-digit
  • \w word character, equivalent to [A-Za-z0-9_]
  • \W non-word character
  • \s whitespace (space, Tab, newline)
  • \S non-whitespace
  • [abc] character class, matches any of a/b/c
  • [^abc] negated class, matches characters that are not a/b/c

Memory trick: d is digit, w is word, s is space — uppercase means “not.”

Quantifiers: greedy vs lazy

Quantifiers control how many times the previous element appears:

  • * zero or more times
  • + one or more times
  • ? zero or one time
  • {n} exactly n times
  • {n,} at least n times
  • {n,m} between n and m times

Key trap: greedy by default — it eats as much as possible. For example, ".*" matching "a" and "b" will return the entire "a" and "b", not two segments. Add ? to make it lazy: ".*?" will get "a" and "b" separately.

When debugging regex, if you suspect the match is too greedy, the first move is to add ?.

Grouping and capturing

Parentheses () are for grouping and have 3 uses:

  • Capture group: Stores the matched content, referenceable later with \1
  • Non-capturing group (?:...): Groups without capturing, saves memory
  • Named capture group (?<name>...): Reference by name, code is more readable

A real example: matching an HTML tag <a href="...">, you want both the tag name and the attributes. Use <\/?([a-z]+)([^>]*)> — the first parens capture the tag name, the second capture the attributes. The named-capture version is <\/?(?<tag>[a-z]+)(?<attrs>[^>]*)>, much more readable.

Regex grouping is more complex than you’d think — the Explain panel in the Piick regex tester breaks down what each paren does, so you don’t have to guess.

5 real-world regex examples

  1. Email [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} — validates common formats; strict RFC 5322 is too long, so use the simplified version in practice
  2. URL https?:\/\/[^\s]+ — matches http/https start to first whitespace
  3. IPv4 \b(?:[0-9]{1,3}\.){3}[0-9]{1,3}\b — 4 segments of 0-255; full validation needs segment-wise numeric comparisons
  4. ISO date \d{4}-\d{2}-\d{2} — format like 2026-06-28
  5. URL slug [a-z0-9]+(?:-[a-z0-9]+)* — lowercase letters/digits with hyphens, the common blog post URL format

Don’t write complex regex in your head — paste it into the Piick regex tester. Write on the left, matches highlight live on the right, change a line and see the effect instantly. That’s 10x faster than repeatedly reloading the page.


Open the Piick regex tester now, paste in some text, and try a regex you’ve never run before.