This is a regex cheat sheet: the character classes, anchors, quantifiers and groups that make up almost every regular expression, in one place. The building blocks are the same across JavaScript, Python, PHP, Java and grep, so learn them once and reuse them everywhere. The differences between those flavors are covered at the end.
Character classes
A character class matches a single character from a set. The backslash shorthands are the ones you will reach for most.
. any character except newline
\d a digit, 0-9
\D any non-digit
\w a word character: a-z A-Z 0-9 _
\W any non-word character
\s whitespace: space, tab, newline
\S any non-whitespace
[abc] exactly one of a, b or c
[^abc] any one character except a, b or c
[a-z] any lowercase letter (a range)
[0-9a-f] one hex digit (ranges combine)Inside square brackets most metacharacters lose their special meaning, so [.?*] matches a literal dot, question mark or asterisk. A ^ as the first character negates the class.
Anchors and boundaries
Anchors match a position rather than a character, so they consume no text.
^ start of the string (or line, in multiline mode)
$ end of the string (or line, in multiline mode)
\b a word boundary (edge of a \w run)
\B not a word boundary
\A start of the whole string (Python, PHP, Java)
\z end of the whole string (PHP, Java)\bcat\b matches cat as a whole word but not the cat inside category. This is the fix for the classic “my pattern matches too much” problem. Python writes the absolute end-of-string anchor as uppercase \Z rather than \z.
Quantifiers
Quantifiers say how many times the preceding token may repeat. By default they are greedy (match as much as possible); add a ? to make them lazy (as little as possible).
* zero or more
+ one or more
? zero or one (optional)
{3} exactly 3
{2,} 2 or more
{2,4} between 2 and 4
*? +? lazy versions (match the fewest)The greedy/lazy distinction matters most with .. On the string <a><b>, the pattern <.*> matches the whole thing, while <.*?> matches just <a>.
Groups and alternation
(abc) a capturing group, remembered as group 1
(?:abc) a non-capturing group (grouping only)
(?<year>\d{4}) a named group, referenced as "year"
a|b alternation: match a OR b
(cat|dog) group the alternation so it is scoped
\1 a backreference to what group 1 matchedUse a plain group ( ) when you want to extract the matched text, and a non-capturing group (?: ) when you only need to apply a quantifier or alternation to a chunk. Named groups make captures readable when a pattern has several.
Lookaround
Lookaround asserts that something is (or is not) next to the current position without including it in the match.
(?=abc) lookahead: followed by abc
(?!abc) negative lookahead: not followed by abc
(?<=abc) lookbehind: preceded by abc
(?<!abc) negative lookbehind: not preceded by abcExample: \d+(?= ?USD) matches the number in 50 USD but leaves USD out of the result.
Flags
i case-insensitive
g global, all matches (JavaScript; Python uses findall, PHP preg_match_all)
m multiline: ^ and $ match at line breaks
s dotall: . also matches newlines
x extended: ignore whitespace in the pattern (Python/PHP)Ready-to-use patterns
Copy these as starting points, then test them against your real data rather than trusting them blindly. A “correct” email or URL regex does not really exist; these are pragmatic and good enough for validation.
^\d{4}-\d{2}-\d{2}$ an ISO date, 2026-09-26
^[\w.+-]+@[\w-]+\.[\w.-]+$ a simple email
^https?://[^\s]+$ an http(s) URL
^#?[0-9a-fA-F]{6}$ a hex color, #1a2b3c
^\+?[\d ()-]{7,}$ a loose phone number
\b\d{1,3}(\.\d{1,3}){3}\b a loose IPv4 (does not cap octets at 255)JavaScript vs. Python vs. PHP vs. grep
The tokens above are shared. What changes is how you write and run the pattern:
- JavaScript. A literal between slashes with flags after:
/\d+/g. Usestr.match(),str.replace()orregex.test(). Named groups and lookbehind are supported in modern engines. - Python. Patterns are strings, so use a raw string to avoid double backslashes:
re.findall(r"\d+", text). Flags are passed as arguments (re.IGNORECASE) or inline as(?i). - PHP. The pattern is a delimited string with flags after the closing delimiter:
preg_match('/\d+/i', $text). PHP uses the PCRE engine, the most feature-rich of the four. - grep. Basic grep needs
\+and\?escaped; usegrep -E(oregrep) for the modern syntax shown here, andgrep -Pfor full Perl-style features like lookaround.
The reliable way to build a pattern is to write a little, test against real samples, then add to it. Paste your expression and some sample text into our free regex tester to see every match and capture group highlighted live, entirely in your browser.