Regular expressions (regex) are patterns used to match, search, and replace text. They power everything from form validation to find-and-replace in your editor. This reference groups the syntax you'll actually use — character classes, anchors, quantifiers, groups, lookarounds, and flags — with a short description and example for each, plus a set of ready-to-use patterns.
Note: regex syntax varies slightly between engines (JavaScript, PCRE, Python, etc.). This sheet focuses on the common core; engine-specific notes are called out where they matter.
Character Classes
Match a single character from a set or category.
| Pattern | Matches | Example |
|---|---|---|
. | Any character except newline | a.c → "abc", "a5c" |
\d | Any digit (0–9) | \d\d → "42" |
\D | Any non-digit | \D → "a", "#" |
\w | Word character (letters, digits, _) | \w+ → "user_1" |
\W | Non-word character | \W → " ", "!" |
\s | Whitespace (space, tab, newline) | a\sb → "a b" |
\S | Non-whitespace | \S+ → "hello" |
[abc] | Any one of a, b, or c | [aeiou] → a vowel |
[^abc] | Any character except a, b, c | [^0-9] → non-digit |
[a-z] | Any character in the range | [a-z] → lowercase letter |
Anchors & Boundaries
Match a position rather than a character.
| Pattern | Matches | Example |
|---|---|---|
^ | Start of string (or line) | ^Hello matches at start |
$ | End of string (or line) | end$ matches at end |
\b | Word boundary | \bcat\b → "cat" not "category" |
\B | Non-word boundary | \Bcat\B → "cat" inside "locator" |
\A | Start of string (PCRE/Python) | anchors to very start |
\Z | End of string (PCRE/Python) | anchors to very end |
Quantifiers
Specify how many times the preceding element must repeat.
| Pattern | Meaning | Example |
|---|---|---|
* | 0 or more | ab* → "a", "abbb" |
+ | 1 or more | ab+ → "ab", "abbb" |
? | 0 or 1 (optional) | colou?r → "color", "colour" |
{n} | Exactly n times | \d{4} → "2026" |
{n,} | n or more times | \d{2,} → "42", "4200" |
{n,m} | Between n and m times | \d{2,4} → 2 to 4 digits |
*? +? ?? | Lazy (match as few as possible) | <.+?> → shortest tag |
Groups & Capturing
Group parts of a pattern and capture matched text.
| Pattern | Meaning | Example |
|---|---|---|
(...) | Capturing group | (ab)+ captures "ab" |
(?:...) | Non-capturing group | (?:ab)+ groups without capturing |
(?<name>...) | Named capturing group | (?<year>\d{4}) |
\1 \2 | Backreference to a group | (\w)\1 → doubled letter "ll" |
\k<name> | Backreference by name | \k<year> |
| `a | b` | Alternation (a OR b) |
Lookarounds
Assert what comes before or after, without consuming characters.
| Pattern | Meaning | Example |
|---|---|---|
(?=...) | Positive lookahead | \d(?=px) → digit before "px" |
(?!...) | Negative lookahead | \d(?!px) → digit not before "px" |
(?<=...) | Positive lookbehind | (?<=\$)\d+ → number after "$" |
(?<!...) | Negative lookbehind | (?<!\$)\d+ → number not after "$" |
Flags & Modifiers
Change how the whole pattern behaves.
| Flag | Name | Effect |
|---|---|---|
g | Global | Find all matches, not just the first |
i | Ignore case | Case-insensitive matching |
m | Multiline | ^ and $ match line starts/ends |
s | Dotall | . also matches newlines |
u | Unicode | Full Unicode matching |
y | Sticky | Match from lastIndex only (JS) |
x | Extended | Ignore whitespace in pattern (PCRE/Python) |
Escaping Special Characters
These metacharacters must be escaped with \ to match literally.
| Character | Escaped | Matches |
|---|---|---|
. | \. | a literal dot |
* | \* | a literal asterisk |
? | \? | a literal question mark |
+ | \+ | a literal plus |
( ) | \( \) | literal parentheses |
[ ] | \[ \] | literal brackets |
{ } | \{ \} | literal braces |
| ` | ` | | |
\ | \\ | a literal backslash |
Ready-to-Use Patterns
Common patterns you can copy and adapt. Always test against your own data — "perfect" validation regexes (especially for email) are famously tricky.
| Use case | Pattern |
|---|---|
| Digits only | ^\d+$ |
| Letters only | ^[A-Za-z]+$ |
| Alphanumeric | ^[A-Za-z0-9]+$ |
| Simple email | ^[^\s@]+@[^\s@]+\.[^\s@]+$ |
| URL (http/https) | ^https?:\/\/[^\s/$.?#].[^\s]*$ |
| Slug | ^[a-z0-9]+(?:-[a-z0-9]+)*$ |
| Hex color | `^#(?:[0-9a-fA-F]{3} |
| Date (YYYY-MM-DD) | ^\d{4}-\d{2}-\d{2}$ |
| Time (24h) | `^([01]\d |
| IPv4 address | `^(?:(?:25[0-5] |
| Leading/trailing whitespace | `^\s+ |
Golden Rules for Writing Regex
- Be as specific as possible — greedy, vague patterns like
.*cause surprising matches. Prefer character classes and lazy quantifiers. - Anchor when validating — wrap validation patterns in
^...$so they match the whole string, not just part of it. - Escape literal metacharacters — a bare
.matches any character, not a dot. - Test before you ship — use a tool like regex101 to check edge cases and avoid catastrophic backtracking.
- Comment complex patterns — with the
xflag (or your language's equivalent), you can add whitespace and comments for readability.
Frequently Asked Questions
What is the difference between greedy and lazy quantifiers?
Greedy quantifiers (*, +) match as much text as possible, while lazy ones
(*?, +?) match as little as possible. Use lazy quantifiers when you want the
shortest match, such as the contents of a single HTML tag.
What's the difference between a capturing and non-capturing group?
A capturing group (...) stores its match for reuse or extraction. A
non-capturing group (?:...) groups a pattern for quantifiers or alternation
without storing it, which is slightly faster and keeps your capture numbering
clean.
How do I make a regex case-insensitive?
Add the i flag. For example, /hello/i matches "Hello", "HELLO", and "hello".
What does the global (g) flag do?
The g flag finds every match in the string instead of stopping at the first.
It's required for operations like replacing all occurrences.
When should I use lookahead and lookbehind?
Use them to assert context without consuming characters — for example, matching
a number only when it follows a $ sign, without including the $ in the
result.
Why is my email or URL regex failing on valid inputs? Fully validating email and URLs with a single regex is notoriously hard. For production, use a simple pattern for a sanity check and rely on real validation (like sending a confirmation email) instead of a "perfect" regex.