Skip to main content

Regex Cheat Sheet: Tokens, Anchors & Quantifiers

A practical regex cheat sheet: character classes, anchors, quantifiers, groups, and the metacharacters you must escape, plus worked examples for real-world patterns.

👤 Tools Hub 📅 Jun 24, 2026 ⏱ 8 min read

The Regex Cheat Sheet: Tokens, Anchors, and Quantifiers Made Simple

This regex cheat sheet is a fast reference to the regular expression syntax you actually use: character classes, anchors, quantifiers, groups, and the metacharacters that need escaping. Regular expressions are tiny pattern-matching programs — a compact language for describing the shape of text so you can search, validate, extract, or replace it. Master a dozen symbols and you can match almost anything.

If you came here for a quick answer, the core is small: . matches any character, \d a digit, \w a word character, * means "zero or more," + means "one or more," ^ and $ anchor to the start and end of a line, and [...] defines a set of allowed characters. Everything else is a combination of these. The tables below give you the full reference, followed by worked examples and the gotchas that cause most regex bugs. To experiment as you read, paste any pattern into our free Regex Tester and watch matches highlight live.

How a Regular Expression Reads

A regex is scanned left to right against your input. Most characters match themselves literally — the pattern cat matches the letters c-a-t in that order. The power comes from metacharacters, which carry special meaning instead of matching literally. The engine tries to make the pattern fit the text, and by default it is "greedy," grabbing as much as it can while still allowing the overall pattern to succeed.

Understanding that one idea — literals plus metacharacters, matched greedily — explains nearly every surprising result you will hit. The cheat sheet that follows groups the metacharacters by job.

Character Classes and Shorthands

Character classes define which characters are allowed at a position. Shorthands are pre-built classes for the most common groups.

TokenMatchesExample
.Any character except newlinea.c matches "abc", "a9c"
\dAny digit (0-9)\d\d matches "42"
\DAny non-digit\D matches "x"
\wWord character (letter, digit, underscore)\w+ matches "user_1"
\WNon-word character\W matches "@"
\sWhitespace (space, tab, newline)\s matches " "
\SNon-whitespace\S matches "k"
[abc]Any one of a, b, or c[aeiou] matches a vowel
[^abc]Any character except a, b, c[^0-9] matches a non-digit
[a-z]Any character in a range[A-Fa-f] matches a hex letter

The uppercase shorthands are always the negation of their lowercase versions: \d is a digit, \D is anything that is not a digit. Inside a class, a caret at the very start ([^...]) negates the whole set.

Anchors and Boundaries

Anchors match positions rather than characters. They have zero width — they assert "you are here" without consuming any text.

TokenAssertsExample
^Start of string (or line in multiline mode)^Hello matches a line starting with Hello
$End of string (or line)end$ matches a line ending in "end"
\bWord boundary\bcat\b matches "cat" but not "category"
\BNot a word boundary\Bcat matches "cat" inside "scat"

The word boundary \b is one of the most useful and most under-used tokens. It is what stops a search for cat from also matching "scatter" and "education."

Quantifiers

Quantifiers control how many times the preceding element may repeat. This is where most real-world patterns get their flexibility.

TokenMeaningExample
*Zero or moreab* matches "a", "ab", "abbb"
+One or moreab+ matches "ab", "abbb" (not "a")
?Zero or one (optional)colou?r matches "color" and "colour"
{n}Exactly n times\d{4} matches a 4-digit year
{n,}n or more times\d{2,} matches 2+ digits
{n,m}Between n and m times\d{1,3} matches 1 to 3 digits
*? +?Lazy versions (match as few as possible)<.*?> matches one tag, not a whole line

By default quantifiers are greedy: .* grabs everything it can. Add a ? to make them lazy, so they grab as little as possible. The difference between greedy and lazy matching is the single biggest source of "why did my regex match too much?" confusion.

Groups and Alternation

Parentheses group part of a pattern so a quantifier can apply to the whole group, and they capture the matched text for reuse. The pipe is alternation — a logical OR.

TokenMeaningExample
(...)Capturing group(ab)+ matches "abab"
(?:...)Non-capturing group(?:https?) groups without capturing
a|bMatch a OR bcat|dog matches either word
\1Backreference to group 1(\w)\1 matches a doubled letter

Escaping: The Metacharacters You Must Escape

To match a metacharacter literally, escape it with a backslash. The characters that need escaping outside a character class are: . ^ $ * + ? ( ) [ ] { } | \ and the forward slash if it delimits your pattern. For example, to match a literal dot in a domain name you write \., and to match a dollar amount you write \$\d+.

Rule of thumb: if a symbol does something special in regex, put a backslash in front of it to match it literally. 3\.14 matches the string "3.14"; 3.14 would also match "3x14".

Worked Examples

Patterns make sense fastest when you see them solve a real problem. Here are common tasks broken down.

Validate a Simple Email Shape

Pattern: ^[\w.+-]+@[\w-]+\.[\w.-]+$. Reading it left to right: anchor to the start, one or more word characters or . + - (the local part), a literal @, one or more word characters or hyphens (the domain), a literal dot, then the top-level domain, anchored to the end. This is a pragmatic shape-check, not a full RFC-compliant validator, but it catches the vast majority of typos.

Match a 24-Hour Time

Pattern: ^([01]\d|2[0-3]):[0-5]\d$. The hour is either 0 or 1 followed by any digit, or 2 followed by 0-3. Then a colon, then minutes from 00 to 59. This shows how alternation inside a group lets you express real-world constraints precisely.

Extract All Hashtags

Pattern: #\w+. The literal # followed by one or more word characters. Run globally over a caption and every hashtag is captured. Add a word boundary or anchor if you need to avoid matching mid-word symbols.

Greedy vs Lazy in Action

Given the text <b>bold</b>, the pattern <.*> greedily matches the entire string, because .* swallows everything up to the last >. The lazy pattern <.*?> matches only <b>. When you want the smallest possible match, reach for the lazy quantifier.

Flags That Change Everything

  • g (global) — find all matches, not just the first. Essential for replace-all and extraction.
  • i (case-insensitive)cat also matches "CAT" and "Cat".
  • m (multiline) — makes ^ and $ match at every line break, not just the string boundaries.
  • s (dotall) — lets . match newline characters too.

Flags are set differently per language, but their meanings are consistent. The fastest way to learn how they interact is to toggle them on a live pattern in the Regex Tester and watch the highlighted matches change in real time.

Putting the Cheat Sheet to Work

The trick with regex is to build patterns incrementally. Start with the literal core, add a character class, then a quantifier, then anchors, testing after each addition. Trying to write the whole pattern in one shot is how you end up with something that almost works but matches three cases too many. Keep this cheat sheet open, test as you go, and explore more developer utilities in the Development Tools hub. If your work touches data formats and IDs, our guides on generating UUIDs in Python and the decimal to ASCII reference are handy companions.

Frequently Asked Questions

What is the difference between greedy and lazy quantifiers?

Greedy quantifiers like * and + match as much text as possible while still allowing the overall pattern to succeed. Lazy quantifiers, written by adding ? (such as *? or +?), match as little as possible. Use lazy quantifiers when you want the shortest match, such as a single HTML tag instead of a whole line.

When do I need to escape a character in regex?

Escape a character with a backslash whenever you want to match a metacharacter literally. The characters needing escaping are . ^ $ * + ? ( ) [ ] { } | \ and your delimiter slash. For example, \. matches a literal dot, while an unescaped . matches any character.

What does the word boundary \b do?

The \b token asserts a position between a word character and a non-word character. It lets you match whole words: \bcat\b matches "cat" as a standalone word but not "category" or "scatter". It matches a position, not an actual character.

What is the difference between a capturing and non-capturing group?

A capturing group (...) both groups a sub-pattern and stores its matched text for backreferences or extraction. A non-capturing group (?:...) only groups, without storing the match. Use non-capturing groups when you need grouping for a quantifier or alternation but do not need to reference the result.

Why does my regex match more text than expected?

Almost always because of greedy quantifiers. By default .* consumes everything it can. Either switch to a lazy quantifier (.*?) or use a more specific character class such as [^>]* so the match cannot overrun past the character you want to stop at.

Do regex flags work the same in every language?

The common flags (global, case-insensitive, multiline, dotall) mean the same thing across most engines, but the syntax for setting them and a few advanced features differ. JavaScript, Python, PCRE, and others share the core token set in this cheat sheet, so patterns are largely portable with minor adjustments.

What does \d{2,4} mean?

It matches between 2 and 4 digits. The {n,m} quantifier sets a minimum and maximum repeat count. So \d{2,4} matches "12", "123", or "1234" but not a single digit or five digits in a row.

How do I match either of two words?

Use alternation with the pipe: cat|dog matches "cat" or "dog". Wrap it in a group when combining with other tokens, for example (cat|dog)s? to optionally match a plural. Non-capturing groups (?:cat|dog) work too if you do not need to capture.

Tools Hub
Free online tools, every day

Share on Social Media:

ads

Please disable your ad blocker!

We understand that ads can be annoying, but please bear with us. We rely on advertisements to keep our website online. Could you please consider whitelisting our website? Thank you!