RegEx Cheat Sheet
Every pattern, anchor, quantifier, group, and flag. Searchable, copy-ready, with live match testing.
Anchors
Character Classes
Quantifiers
Groups
Lookaround
Flags
Escapes
Common Patterns
Most developers have copy-pasted a regex pattern at least once without fully understanding what it does. That works, until it doesn't.
Regular expressions are one of those tools that seem cryptic at first but make a lot of sense once the syntax clicks. Pattern matching, input validation, string manipulation, find and replace across files - regex handles all of it.
This regex cheat sheet covers the core syntax you actually need: character classes, quantifiers, anchors, capture groups, lookaheads, and common patterns across Python, JavaScript, and other languages.
Bookmark it. You'll come back to it.
What is RegEx
A regular expression (RegEx) is a sequence of characters that defines a search pattern used to match, find, or manipulate text.
It works across almost every programming language: Python, JavaScript, PHP, Java, Ruby, and more.
Not a formatting tool. Not a beautifier. A precision instrument for string manipulation, input validation, text parsing, and pattern matching.
RegEx Syntax
RegEx syntax is built from a small set of rules. Learn these, and every pattern starts to make sense.
Special Characters
These characters have reserved meaning in any regular expression engine:
|
Character |
Meaning |
|---|---|
|
|
Matches any single character except newline |
|
|
Start of string (or line in multiline mode) |
|
|
End of string (or line in multiline mode) |
|
|
Zero or more repetitions |
|
|
One or more repetitions |
|
|
Zero or one repetition (also makes quantifiers lazy) |
|
|
Escape character |
|
` |
` |
|
|
Capturing group |
|
|
Character class |
|
|
Quantifier range |
Literal Characters
Any character not listed above matches itself literally.
cat matches the exact string "cat" - case-sensitive by default.
Escape Sequences
Use \ before a special character to match it literally.
|
Sequence |
Matches |
|---|---|
|
|
A literal dot |
|
|
A literal asterisk |
|
|
A literal opening parenthesis |
|
|
A literal backslash |
|
|
Newline |
|
|
Tab |
|
|
Carriage return |
RegEx Character Classes
Character classes let you match any one character from a defined set.
Predefined Character Classes
|
Class |
Description |
Matches |
|---|---|---|
|
|
Digit |
|
|
|
Non-digit |
Anything except |
|
|
Word character |
|
|
|
Non-word character |
Anything |
|
|
Whitespace |
Space, tab, newline |
|
|
Non-whitespace |
Anything |
|
|
Any character |
Except newline (by default) |
Custom Character Classes
Square brackets define a custom set. [aeiou] matches any single vowel.
Ranges work too: [a-z] matches any lowercase letter, [0-9] matches any digit, [a-zA-Z0-9] matches any alphanumeric character.
[aeiou] → matches a, e, i, o, or u
[a-z] → matches any lowercase letter
[A-Za-z0-9] → matches any alphanumeric character
[.,!?] → matches any of these punctuation marks
Negated Character Classes
Add ^ inside brackets to match anything NOT in the set.
[^aeiou] → matches any character that is NOT a vowel
[^0-9] → matches any non-digit character
[^\s] → matches any non-whitespace character
RegEx Quantifiers
Quantifiers control how many times a pattern repeats.
Greedy Quantifiers
Greedy quantifiers match as much as possible. They're the default behavior.
|
Quantifier |
Meaning |
Example |
|---|---|---|
|
|
0 or more |
|
|
|
1 or more |
|
|
|
0 or 1 |
|
|
|
Exactly n times |
|
|
|
n or more times |
|
|
|
Between n and m times |
|
Lazy Quantifiers
Add ? after any greedy quantifier to make it lazy - matches as little as possible.
|
Quantifier |
Meaning |
|---|---|
|
|
0 or more (lazy) |
|
|
1 or more (lazy) |
|
|
0 or 1 (lazy) |
|
|
Between n and m (lazy) |
Input: <b>bold</b>
Greedy: <.+> → matches <b>bold</b> (entire string)
Lazy: <.+?> → matches <b> (stops at first >)
Possessive Quantifiers
Supported in Java, PCRE, and a few other engines. Not available in JavaScript.
They match greedily and never give back characters, which can prevent backtracking.
|
Quantifier |
Meaning |
|---|---|
|
|
0 or more (possessive) |
|
|
1 or more (possessive) |
|
|
0 or 1 (possessive) |
RegEx Anchors and Boundaries
Anchors don't match characters. They match positions in a string.
Start and End Anchors
|
Anchor |
Matches |
|---|---|
|
|
Start of string (or line with |
|
|
End of string (or line with |
|
|
Start of string (ignores |
|
|
End of string (ignores |
^Hello → matches "Hello" only at the start
world$ → matches "world" only at the end
^\d{3}-\d{4}$ → matches exactly "123-4567" and nothing else
Word Boundaries
Word boundaries match the position between a word character (\w) and a non-word character (\W).
|
Boundary |
Matches |
|---|---|
|
|
Word boundary |
|
|
Non-word boundary |
\bcat\b → matches "cat" in "the cat sat" but NOT in "category"
\Bcat\B → matches "cat" inside "concatenate" but NOT as a standalone word
Line vs String Anchors
By default, ^ and $ match the start and end of the entire string.
Enable multiline mode (m flag) and they match the start and end of each individual line instead.
Without m flag: ^cat$ → only matches if the entire string is "cat"
With m flag: ^cat$ → matches "cat" on any line within a multiline string
RegEx Groups and Capturing
Groups let you isolate, reuse, and reference parts of a matched pattern.
Capturing Groups
Wrap any pattern in () to capture it. The engine stores the match so you can reference it later.
(\d{4})-(\d{2})-(\d{2})
→ Matches "2024-01-15", captures year, month, day in groups 1, 2, 3
Non-Capturing Groups
(?:...) groups without storing the match. Use when you need grouping for structure but don't need the captured value.
(?:https?|ftp):// → groups "https", "http", or "ftp" without capturing
Named Capturing Groups
Assign a name instead of a number. Cleaner to reference, especially in long patterns.
(?P<year>\d{4})-(?P<month>\d{2}) # Python
(?<year>\d{4})-(?<month>\d{2}) # JavaScript, .NET, Java
Access via match.group('year') in Python or match.groups.year in JavaScript.
Backreferences
Reference a previously captured group inside the same pattern using \1, \2, etc.
(\w+)\s\1 → matches repeated words like "the the" or "go go"
RegEx Lookahead and Lookbehind
Lookarounds check what surrounds a match without including that context in the result.
Zero-width assertions. They check position, not content.
Positive Lookahead
(?=...) matches if what follows fits the pattern.
\d+(?= dollars) → matches "100" in "100 dollars" but not in "100 euros"
Negative Lookahead
(?!...) matches if what follows does NOT fit the pattern.
\d+(?! dollars) → matches "100" in "100 euros" but skips "100 dollars"
Positive Lookbehind
(?<=...) matches if what precedes fits the pattern.
(?<=\$)\d+ → matches "99" in "$99" but not in "99 USD"
Negative Lookbehind
(?<!...) matches if what precedes does NOT fit the pattern.
(?<!\$)\d+ → matches "99" in "99 USD" but skips "$99"
Note: JavaScript (pre-ES2018) does not support lookbehind. Most other major engines do.
RegEx Flags and Modifiers
Flags change how the entire pattern behaves. Placed after the closing delimiter or passed as a second argument.
|
Flag |
Name |
Effect |
Example |
|---|---|---|---|
|
|
Case insensitive |
|
|
|
|
Global |
Find all matches, not just the first |
|
|
|
Multiline |
|
|
|
|
Dotall |
|
|
|
|
Extended |
Allows whitespace and comments in patterns |
Supported in Python, PHP, Ruby |
|
|
Unicode |
Enables full Unicode support |
|
/hello/gi → matches "hello", "Hello", "HELLO" anywhere in the string
RegEx Syntax by Language
The core syntax is consistent. Delimiters, flags, and a few edge cases vary by language.
RegEx in JavaScript
Uses RegExp object or literal /pattern/flags syntax. Lookbehind requires ES2018+.
const pattern = /^\d{4}-\d{2}-\d{2}$/;
pattern.test("2024-01-15"); // true
const matches = "one 1, two 2".match(/\d+/g); // ["1", "2"]
Key methods: .test(), .match(), .replace(), .split(), .exec()
RegEx in Python
Uses the built-in re module. Supports named groups, lookbehind, and verbose mode (re.X).
import re
pattern = re.compile(r"(\d{4})-(\d{2})-(\d{2})")
match = pattern.search("Date: 2024-01-15")
print(match.group(1)) # "2024"
Key functions: re.search(), re.match(), re.findall(), re.sub(), re.compile()
RegEx in PHP
Uses PCRE via preg_* functions. Patterns wrapped in delimiters (usually /).
preg_match('/(\d{4})-(\d{2})/', '2024-01', $matches);
echo $matches[1]; // "2024"
preg_replace('/\s+/', '-', 'hello world'); // "hello-world"
Key functions: preg_match(), preg_match_all(), preg_replace(), preg_split()
RegEx in Java
Uses java.util.regex package. Patterns compiled from strings - backslashes need escaping (\\d not \d).
import java.util.regex.*;
Pattern p = Pattern.compile("(\\d{4})-(\\d{2})-(\\d{2})");
Matcher m = p.matcher("2024-01-15");
if (m.find()) {
System.out.println(m.group(1)); // "2024"
}
Key classes: Pattern, Matcher
RegEx in Ruby
Uses the Regexp class or literal /pattern/ syntax. Named groups work cleanly with symbol access.
str = "2024-01-15"
match = str.match(/(?<year>\d{4})-(?<month>\d{2})/)
puts match[:year] # "2024"
Key methods: .match(), .scan(), .gsub(), .split()
Common RegEx Patterns
Patterns you'll actually use. Copy, test, adjust for your input.
|
Use Case |
Pattern |
Notes |
|---|---|---|
|
|
|
Basic validation; RFC 5322 is far more complex |
|
URL |
|
Simplified - use a library for production |
|
Phone (US) |
|
Handles common US formats |
|
IP Address (IPv4) |
|
Does not validate the 0–255 range |
|
Date (YYYY-MM-DD) |
|
Validates month and day ranges |
|
HTML tag |
|
Matches any tag - not for parsing full HTML |
|
Whitespace (trim) |
|
Matches leading and trailing whitespace |
|
Password |
|
8+ chars, uppercase, digit, special char |
|
Hex color |
|
Matches 3 or 6 digit hex codes |
|
Username |
|
3–16 alphanumeric characters or underscores |
RegEx Operators and Alternation
Pipe Operator
| acts as a logical OR between two expressions.
cat|dog → matches "cat" or "dog"
jpg|jpeg|png → matches any of these file extensions
Precedence Rules
Alternation has the lowest precedence in a regular expression.
cat|dog food matches "cat" OR "dog food", not "cat food" OR "dog food". Wrap in a group to control scope: (cat|dog) food.
Grouping with Alternation
Combine alternation with groups to build clean branching patterns.
^(Mr|Mrs|Ms|Dr)\. [A-Z][a-z]+$
→ matches "Dr. Smith", "Ms. Jones"
How to Test RegEx
Online RegEx Testers
These tools give real-time match highlighting, group inspection, and engine selection.
-
Regex101 - best overall; supports PCRE, JavaScript, Python, Go; explains each token inline
-
Regexr - clean interface, good for beginners learning pattern matching
-
Debuggex - renders a visual NFA/DFA diagram of your pattern
RegEx Debugging Tips
-
Test against both matching and non-matching strings
-
Break complex patterns into smaller pieces, then build up
-
Use verbose mode (
xflag) to add whitespace and inline comments -
Check for catastrophic backtracking before running on large inputs
-
Regex101's step-through debugger shows exactly how the engine processes each character
RegEx Performance and Backtracking
Backtracking happens when the engine tries a path, fails, then backs up and retries.
Minor backtracking is normal. Catastrophic backtracking is a bug - it can freeze an application on specific inputs.
What Causes It
Nested quantifiers on overlapping patterns. (a+)+b on a string like "aaaaaa" with no b at the end triggers an exponential number of retries.
Other common causes:
-
(.+)*or(.*)+- redundant quantifier nesting -
Alternation with shared prefixes:
(cat|catch)- use(cat(?:ch)?)instead -
Overly broad
.+patterns mid-string with nothing to anchor the match
How to Avoid It
-
Use possessive quantifiers (
*+,++) in engines that support them - Java, PCRE -
Use atomic groups
(?>...)in PCRE/Java to prevent backtracking into a completed group -
Prefer specific character classes over
.wherever possible -
Test adversarial inputs on Regex101's debugger before shipping to a production environment
-
During the code review process, flag any pattern with nested quantifiers for manual testing
FAQ on Regex
What is RegEx used for?
RegEx is used for pattern matching, input validation, text parsing, and string manipulation.
Common applications: validating email addresses, extracting URLs, finding duplicates, parsing log files, and running find-and-replace across large codebases.
What does .* mean in RegEx?
. matches any single character except a newline.
* is a greedy quantifier meaning zero or more repetitions. Together, .* matches any sequence of characters on a single line - as much as possible.
What is the difference between greedy and lazy quantifiers?
Greedy quantifiers match as much text as possible. Lazy quantifiers (add ?) match as little as possible.
<.+> grabs everything between the first < and the last >. <.+?> stops at the first > it finds.
What does ^ mean in a RegEx pattern?
Outside a character class, ^ is a start anchor - it matches the position at the beginning of a string.
Inside brackets like [^abc], it negates the set, matching any character that is NOT a, b, or c.
What are RegEx flags?
Flags modify how the regex engine processes a pattern.
Common ones: i (case-insensitive), g (global - find all matches), m (multiline - ^ and $ match per line), s (dotall - . matches newlines too).
What is a capturing group in RegEx?
Parentheses () create a capturing group, storing the matched text for later use via backreferences or in replacement strings.
Non-capturing groups (?:...) group without storing. Named groups (?<name>...) let you reference matches by name instead of index.
How do word boundaries work in RegEx?
\b matches the position between a word character (\w) and a non-word character (\W).
\bcat\b matches "cat" as a standalone word but skips "category" or "concatenate". Useful for precise string search without partial matches.
Does RegEx syntax differ between programming languages?
Yes. Core syntax is consistent, but engine-specific features vary.
JavaScript lacks lookbehind in older versions and has no possessive quantifiers. Python's re module supports named groups. PCRE (used in PHP) is the most feature-complete regex flavor available.
What is catastrophic backtracking in RegEx?
It happens when a pattern with nested quantifiers - like (a+)+ - tries an exponential number of combinations on a non-matching string.
The regex engine keeps retrying, causing serious performance slowdowns. Fix it by rewriting ambiguous patterns or using possessive quantifiers where supported.
How do I test a RegEx pattern?
Use an online regex tester like Regex101, Regexr, or Debuggex.
These tools show real-time match highlighting, break down each part of your pattern, and let you switch between regex flavors like PCRE, JavaScript, and Python.