Regex Cheat Sheet: Syntax and Real Examples You Can Copy
A practical regular expression cheat sheet: characters, quantifiers, groups, lookarounds and flags, plus tested patterns for emails, dates, logs and more.
· 6 min read
Contents
- Characters and classes
- Anchors and boundaries
- Quantifiers
- Greedy vs lazy
- Groups and alternation
- Lookarounds
- Flags
- Real-world patterns
- Email (practical, not RFC-complete)
- Date in YYYY-MM-DD format
- Time (24-hour HH:MM)
- IPv4 address
- URL slug
- Strong password check
- Hex color
- Semantic version
- Parse a log line
- Find trailing whitespace (editor search)
- Using regex in code
- JavaScript
- Python
- Command line (grep and sed)
- Common mistakes
- FAQ
- Are regexes the same in every language?
- How do I test a regex?
- What does (?:...) mean?
- Further reading
Regular expressions look cryptic, but they are built from a small set of pieces. Once you know those pieces you can read most patterns, and write the ones you need for validation, search-and-replace and log parsing.
This cheat sheet covers the syntax shared by JavaScript, Python, Java, Go, PHP and most editors, followed by real-world patterns with explanations. Try any of them live in our regex tester.
Characters and classes
| Pattern | Matches |
|---|---|
abc | The literal text "abc" |
. | Any character except a newline |
\d | A digit (0–9) |
\w | A word character: letter, digit or underscore |
\s | Whitespace: space, tab, newline |
\D, \W, \S | The opposite of \d, \w, \s |
[abc] | One of a, b or c |
[^abc] | Any character except a, b or c |
[a-z] | A lowercase letter |
[A-Za-z0-9_-] | A letter, digit, underscore or hyphen |
\. | A literal dot (escape special characters with \) |
Characters with special meaning that must be escaped to match literally: . ^ $ * + ? ( ) [ ] { } | \ /.
Anchors and boundaries
| Pattern | Matches |
|---|---|
^ | Start of the string (or line, with the m flag) |
$ | End of the string (or line, with the m flag) |
\b | A word boundary |
\B | Not a word boundary |
\bcat\b matches "cat" in "the cat sat" but not in "concatenate".
Quantifiers
| Pattern | Meaning |
|---|---|
* | 0 or more |
+ | 1 or more |
? | 0 or 1 (optional) |
{3} | Exactly 3 |
{2,} | 2 or more |
{2,5} | Between 2 and 5 |
*?, +?, ?? | Lazy versions: match as little as possible |
Greedy vs lazy
Quantifiers are greedy by default — they match as much as possible:
Text: <b>bold</b> and <b>more</b>
<b>.*</b> → "<b>bold</b> and <b>more</b>" (greedy, one big match)
<b>.*?</b> → "<b>bold</b>", "<b>more</b>" (lazy, two matches)
Groups and alternation
| Pattern | Meaning |
|---|---|
(abc) | Capturing group |
(?:abc) | Non-capturing group (grouping without saving) |
(?<year>\d{4}) | Named group (Python also accepts (?P<year>...)) |
a|b | a or b |
\1 | Back-reference to group 1 |
(\w+) \1 finds doubled words like "the the".
Lookarounds
Lookarounds check what comes before or after without including it in the match.
| Pattern | Meaning |
|---|---|
X(?=Y) | X followed by Y |
X(?!Y) | X not followed by Y |
(?<=Y)X | X preceded by Y |
(?<!Y)X | X not preceded by Y |
\d+(?= USD) matches "250" in "250 USD" without the currency. Go's standard regexp package does not support lookarounds.
Flags
| Flag | Effect |
|---|---|
i | Case-insensitive |
g | Global: find all matches (JavaScript) |
m | Multiline: ^ and $ match at each line |
s | Dot matches newlines too |
x | Verbose: ignore whitespace and allow comments (Python, PCRE) |
Real-world patterns
Email (practical, not RFC-complete)
^[^\s@]+@[^\s@]+\.[^\s@]+$
"Something without spaces, an @, something, a dot, something." Fully validating email addresses with a regex is not practical — the only real test is sending a confirmation email. This pattern catches typos without rejecting valid addresses.
Date in YYYY-MM-DD format
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
Checks the shape and the month/day ranges. It still allows impossible dates like 2026-02-31, so parse with a date library for real validation.
Time (24-hour HH:MM)
^([01]\d|2[0-3]):[0-5]\d$
IPv4 address
^((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$
Each part allows only 0–255.
URL slug
^[a-z0-9]+(?:-[a-z0-9]+)*$
Lowercase words separated by single hyphens, like regex-cheat-sheet.
Strong password check
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d).{12,}$
At least 12 characters with a lowercase letter, an uppercase letter and a digit — each lookahead checks one rule. (Length matters more than complexity; consider just requiring a long passphrase.)
Hex color
^#(?:[0-9a-fA-F]{3}){1,2}$
Matches #fff and #1d5fd1.
Semantic version
^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$
Matches 1.4.2 and 2.0.0-beta.1.
Parse a log line
^(?<time>\S+) (?<level>INFO|WARN|ERROR) (?<service>[\w-]+) (?<message>.*)$
Applied to 2026-10-28T09:15:02Z WARN payment-service timeout after 30s, the named groups give you time, level, service and message.
Find trailing whitespace (editor search)
[ \t]+$
With the multiline flag, this finds spaces or tabs at the end of every line — replace with nothing to clean a file.
Using regex in code
JavaScript
const re = /^(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})$/;
const m = "2026-10-28".match(re);
console.log(m.groups.year); // "2026"
"a1b22c333".replace(/\d+/g, "#"); // "a#b#c#"
[..."x=1, y=22".matchAll(/(\w)=(\d+)/g)].map(m => m[2]); // ["1", "22"]
Python
import re
m = re.fullmatch(r"(?P<year>\d{4})-(?P<month>\d{2})-(?P<day>\d{2})", "2026-10-28")
print(m["year"]) # 2026
re.sub(r"\d+", "#", "a1b22c333") # 'a#b#c#'
re.findall(r"(\w)=(\d+)", "x=1, y=22") # [('x', '1'), ('y', '22')]
Use raw strings (r"...") in Python so backslashes reach the regex engine unchanged. re.fullmatch requires the whole string to match; re.search finds a match anywhere.
Command line (grep and sed)
grep -E 'ERROR|WARN' app.log # extended regex
grep -oE '[0-9]{1,3}(\.[0-9]{1,3}){3}' access.log | sort | uniq -c # count IPs
sed -E 's/[[:space:]]+$//' file.txt # strip trailing whitespace
grep and sed use POSIX regex: \d is not supported everywhere, so use [0-9] or [[:digit:]]. GNU grep's -P flag enables Perl-style syntax.
Common mistakes
- Forgetting anchors in validation.
\d{5}matches inside "abc123456xyz". Use^\d{5}$(orfullmatch) to validate the whole string. - Unescaped dots.
example.comalso matches "exampleXcom". Writeexample\.com. - Greedy quantifiers across too much text. Use lazy quantifiers or a negated class like
[^"]*instead of.*. - Catastrophic backtracking. Nested quantifiers such as
(a+)+can take exponential time on some inputs, freezing a server. Keep patterns simple, and never run user-supplied regexes without a timeout. - Parsing HTML or JSON with regex. Use a real parser — regex breaks on nesting and edge cases.
FAQ
Are regexes the same in every language?
The core syntax is shared, but details differ: lookbehind support, named-group syntax, Unicode handling and flags. Test patterns in the language you will use.
How do I test a regex?
Paste it into our free regex tester, which highlights matches and explains each part of the pattern, or write a small unit test with matching and non-matching examples — the test keeps working when you edit the pattern later.
What does (?:...) mean?
A non-capturing group: it groups part of a pattern (for alternation or quantifiers) without creating a numbered capture.
Further reading
Keep reading
Makefiles for Modern Projects: A Practical Tutorial
Use a Makefile as your project's command menu: targets, phony targets, variables, dependencies, a self-documenting help target and a real-world example.
How to Undo Almost Anything in Git (Without Losing Work)
Undo the last commit, unstage files, discard changes, fix a bad merge or recover deleted commits. Every Git undo scenario with the exact command to use.
25 Git Commands Every Developer Should Know (With Examples)
The Git commands you will use every week, grouped by task, with real examples and the safe way to undo mistakes before they reach your team.