Regex cheat sheet: the patterns you actually use
Regular expressions describe text patterns with a compact syntax that is easy to forget between uses. This cheat sheet covers the syntax that comes up in real work, in the order you are likely to need it, with examples you can paste into the Regex Tester and adjust live in your browser.
Everything below uses JavaScript flavor syntax, which is also what browsers, Node, and most modern tooling use. Where other flavors differ in ways that bite people, it is called out.
Character classes: matching one character
| Pattern | Matches |
|---|---|
. | Any character except newline |
\d | A digit, 0 to 9 |
\D | Anything that is not a digit |
\w | A word character: letter, digit, or underscore |
\W | Anything that is not a word character |
\s | Whitespace: space, tab, newline |
\S | Anything that is not whitespace |
[abc] | One of a, b, or c |
[^abc] | Any character except a, b, or c |
[a-z0-9] | One character in either range |
Inside square brackets most special characters lose their meaning. [.+*] matches a literal dot, plus, or asterisk. The exceptions are ], \, ^ at the start, and - between characters.
Quantifiers: how many times
| Pattern | Matches |
|---|---|
a* | Zero or more a |
a+ | One or more a |
a? | Zero or one a |
a{3} | Exactly three |
a{2,4} | Two to four |
a{2,} | Two or more |
Quantifiers are greedy by default: they match as much as possible. ".*" applied to "one" and "two" matches the whole string from the first quote to the last one, which is rarely what you want. Add ? to make a quantifier lazy: ".*?" stops at the first closing quote.
A more robust fix than laziness is a negated class: "[^"]*" matches a quote, then anything that is not a quote, then a quote. It cannot overrun, and it is faster.
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 |
Anchors match positions, not characters. ^cat$ matches the string cat and nothing else. \bcat\b finds cat as a whole word inside a longer text, so it matches in the cat sat but not in concatenate.
If you are validating an entire value, always anchor with ^ and $. Without anchors, \d{4} happily matches inside abc12345xyz, and validation that only checks for a match will pass input it should reject.
Groups and alternation
| Pattern | Meaning |
|---|---|
(abc) | Capturing group |
(?:abc) | Non capturing group |
(?<name>abc) | Named capturing group |
a|b | a or b |
\1 | Backreference to group 1 |
Alternation has low precedence, so ^cat|dog$ means "starts with cat, or ends with dog". Group it to get what you probably meant: ^(?:cat|dog)$.
Use non capturing groups (?:...) when you only need grouping, not the captured text. It keeps group numbering stable and makes intent clear. For anything you do extract, named groups are easier to maintain: (?<year>\d{4})-(?<month>\d{2}) reads better than counting parentheses.
Backreferences match the same text a group already matched. (\w+) \1 finds repeated words like the the.
Lookahead and lookbehind
| Pattern | Meaning |
|---|---|
(?=abc) | Followed by abc |
(?!abc) | Not followed by abc |
(?<=abc) | Preceded by abc |
(?<!abc) | Not preceded by abc |
Lookarounds assert without consuming characters. \d+(?= dollars) matches 40 in 40 dollars but the match itself is just the digits. They are covered in depth in our lookahead and lookbehind guide.
Flags
| Flag | Effect |
|---|---|
g | Global: find all matches, not just the first |
i | Case insensitive |
m | Multiline: ^ and $ match at line breaks |
s | Dot matches newlines too |
u | Unicode mode, correct handling of characters outside the basic plane |
The one that surprises people is m. Without it, ^ and $ mean the start and end of the whole input, even if the input has many lines.
Ready to use patterns
These are practical patterns, tested and anchored. Paste them into the Regex Tester with your own sample data before trusting them.
Email (pragmatic):
^[^\s@]+@[^\s@]+\.[^\s@]+$
Intentionally loose. A fully RFC compliant email regex is enormous and still cannot tell you whether the mailbox exists. Why loose is correct here is the subject of our email validation regex post.
URL (http and https):
^https?:\/\/[^\s/$.?#].[^\s]*$
ISO 8601 date (YYYY-MM-DD):
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$
This checks the shape and the ranges, but not calendar validity. It accepts February 31. Parse the date after matching if that matters.
Integer or decimal number, optional sign:
^-?\d+(\.\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)$
Semantic version (major.minor.patch):
^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$
UUID:
^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$
Use with the i flag if input may be uppercase.
Slug (lowercase, digits, single separators):
^[a-z0-9]+(?:-[a-z0-9]+)*$
Trim whitespace (for replace, with the g flag):
^\s+|\s+$
Escaping: which characters need a backslash
Outside character classes, these have special meaning and need escaping to match literally:
. * + ? ^ $ { } ( ) [ ] | \ /
The most common bug in hand written patterns is an unescaped dot. example.com as a pattern matches exampleXcom too, because . means any character. Write example\.com.
Common mistakes worth knowing
- Forgetting anchors during validation. An unanchored pattern matches anywhere inside the input.
- Greedy
.*across delimiters. Prefer a negated character class like[^"]*. - Using regex to parse HTML or JSON. Nested structures need a real parser. Regex works on fragments, not on the full grammar.
- Catastrophic backtracking. Nested quantifiers like
(a+)+against a long non matching input can hang. If a pattern feels slow, simplify the nesting. - Assuming one flavor. Lookbehind, named groups, and
\dUnicode behavior vary across languages. Test in the environment where the pattern will run.
Everything here runs entirely in your browser in the Regex Tester, with live match highlighting and a capture group table, so you can verify a pattern against real sample data before it goes anywhere near production.