Published March 27, 2026 · 15 min read
Regular expressions are one of the most powerful tools in programming, and also one of the most confusing. This cheat sheet covers every regex pattern you will actually use in practice, with real examples you can test immediately in our free Regex Tester.
Bookmark this page. You will come back to it.
| Pattern | Description | Example | Matches |
|---|---|---|---|
. | Any character except newline | h.t | hat, hot, hit |
\ | Escape special character | \. | literal dot |
| | OR operator | cat|dog | cat or dog |
The dot is the most common beginner pitfall. It matches almost everything, which means it often matches more than you intended. When you want a literal dot (like in a domain name), always escape it: \.
https?://[\w.-]+\.\w+| Pattern | Description | Equivalent |
|---|---|---|
[abc] | Any one of a, b, or c | a|b|c |
[^abc] | Any character NOT a, b, or c | — |
[a-z] | Any lowercase letter | — |
[A-Z] | Any uppercase letter | — |
[0-9] | Any digit | \d |
\d | Any digit | [0-9] |
\D | Any non-digit | [^0-9] |
\w | Word character | [a-zA-Z0-9_] |
\W | Non-word character | [^a-zA-Z0-9_] |
\s | Whitespace (space, tab, newline) | [ \t\n\r\f\v] |
\S | Non-whitespace | [^ \t\n\r\f\v] |
Pro tip: \w includes the underscore character. This is why it works well for matching variable names in most programming languages, but it will not match hyphens in CSS class names. Use [\w-] for CSS selectors.
| Pattern | Description | Example | Matches |
|---|---|---|---|
* | 0 or more | ab*c | ac, abc, abbc, abbbc |
+ | 1 or more | ab+c | abc, abbc, abbbc (not ac) |
? | 0 or 1 | colou?r | color, colour |
{n} | Exactly n times | \d{4} | 1234, 5678 |
{n,} | n or more times | \d{2,} | 12, 123, 1234 |
{n,m} | Between n and m times | \d{2,4} | 12, 123, 1234 |
*? | 0 or more (lazy) | <.*?> | matches shortest tag |
+? | 1 or more (lazy) | ".+?" | matches shortest quoted string |
By default, quantifiers are greedy — they match as much as possible. This causes problems when parsing HTML or extracting quoted strings.
<.+><.+?>| Pattern | Description | Example |
|---|---|---|
^ | Start of string (or line with m flag) | ^Hello |
$ | End of string (or line with m flag) | world$ |
\b | Word boundary | \bcat\b matches "cat" not "cats" |
\B | Non-word boundary | \Bcat\B matches "concatenate" |
Word boundaries are incredibly useful for searching code. \bfunction\b matches the keyword "function" without matching "malfunction" or "dysfunction." Always use \b when searching for exact words.
| Pattern | Description | Example |
|---|---|---|
(abc) | Capturing group | (\d{3})-(\d{4}) |
(?:abc) | Non-capturing group | (?:https?|ftp):// |
(?<name>abc) | Named capturing group | (?<year>\d{4}) |
\1 | Backreference to group 1 | (\w+)\s\1 matches repeated words |
(?<month>\d{2})/(?<day>\d{2})/(?<year>\d{4})Named groups make your regex self-documenting. Instead of remembering that group 1 is the month and group 2 is the day, you access them by name. Every modern regex engine supports this syntax.
| Pattern | Description | Example |
|---|---|---|
(?=abc) | Positive lookahead | \d+(?=px) matches digits before "px" |
(?!abc) | Negative lookahead | \d+(?!px) matches digits NOT before "px" |
(?<=abc) | Positive lookbehind | (?<=\$)\d+ matches digits after "$" |
(?<!abc) | Negative lookbehind | (?<!\$)\d+ matches digits NOT after "$" |
Lookarounds are zero-width assertions. They check if something exists before or after your match without including it in the result. This is essential for extracting data from structured text.
(?<=\$)\d+\.?\d*| Flag | Description | Usage |
|---|---|---|
g | Global — find all matches, not just first | /pattern/g |
i | Case insensitive | /hello/i matches Hello, HELLO |
m | Multiline — ^ and $ match line start/end | /^start/m |
s | Dotall — dot matches newlines too | /start.*end/s |
u | Unicode — proper Unicode character handling | /\p{Emoji}/u |
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$
This is not RFC 5322 compliant (that regex is 6,000+ characters), but it validates 99.9% of real email addresses correctly.
https?:\/\/[\w\-._~:/?#\[\]@!$&'()*+,;=%]+
^(\+1)?[\s.-]?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$
Matches: 555-123-4567, (555) 123-4567, +1 555.123.4567, 5551234567
^(?:(?:25[0-5]|2[0-4]\d|[01]?\d\d?)\.){3}(?:25[0-5]|2[0-4]\d|[01]?\d\d?)$
^#?([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$
Requires: 8+ characters, one uppercase, one lowercase, one digit, one special character.
<(\w+)(?:\s[^>]*)?\/?>
([\w-]+)\s*:\s*([^;]+);
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
// Test if a string matches
const emailRegex = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
emailRegex.test('user@example.com'); // true
// Extract matches
const text = 'Price: $49.99 and $29.99';
const prices = text.match(/(?<=\$)\d+\.?\d*/g);
// prices = ['49.99', '29.99']
// Named groups with exec
const dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const result = dateRegex.exec('2026-03-27');
// result.groups.year = '2026'
// Replace with pattern
'hello world'.replace(/(\w+)\s(\w+)/, '$2 $1');
// 'world hello'
// Replace with function
'abc'.replace(/[a-c]/g, match => match.toUpperCase());
// 'ABC'
(a+)+ can take exponential time on certain inputs. Use atomic groups or possessive quantifiers when available.[0-9] is faster than . when you know you are matching digits. Specificity reduces the regex engine's work.^pattern is faster than pattern alone because the engine does not need to try matching at every position.(?:abc) is slightly faster than (abc) when you do not need the captured value.const re = /pattern/g;Our free regex tester shows matches in real time with highlighted groups, flags, and explanations.
Open Regex Tester All 650+ Free Tools