Regex Cheat Sheet: Every Pattern You Actually Use, With Live Examples
Every regex reference lists the same symbols. This one also tells you which of them bite: the greedy quantifier, the alternation that ignores your anchors, and the nested quantifier that can pin a CPU core.
The whole language on one screen
A regular expression is a tiny pattern language for describing text. Almost all of it comes down to four ideas: where a match may start and end (anchors), what characters are allowed (classes), how many of them (quantifiers), and which part you want back (groups). Everything below uses JavaScript syntax, because that is what the browser — and CheckSEO's Regex Tester — actually runs. Where Python, PCRE, or Java differ in a way that will bite you, it is called out.
Anchors and boundaries
^— start of the string (start of each line with themflag).$— end of the string (end of each line withm).\b— word boundary.\bcat\bmatches cat but not category.\B— not a word boundary. Useful for finding a fragment inside longer words.
Character classes
.— any character except a newline, unless thesflag is on.\d/\D— a digit[0-9]/ anything that is not a digit.\w/\W— a word character[A-Za-z0-9_]/ anything else. Note the underscore is included and accented letters are not.\s/\S— whitespace (space, tab, newline) / non-whitespace.[abc]— any one of a, b, c.[a-z]— a range.[^abc]— anything but a, b, or c. The^only means "not" when it is the first character inside the brackets.- Inside
[ ]most metacharacters lose their power.[.+*]matches a literal dot, plus, or asterisk — no backslashes needed.
Quantifiers, and the greedy trap
*— zero or more.+— one or more.?— zero or one (optional).{3}— exactly three.{3,}— three or more.{3,5}— between three and five.- Adding
?after any quantifier makes it lazy: it stops at the first possible end instead of the last. This is the single most common regex bug. Against<b>one</b> <b>two</b>, the pattern<b>.*</b>swallows the entire line, while<b>.*?</b>correctly returns just<b>one</b>.
Groups and alternation
( )— a capturing group. Its contents come back in the match result and can be reused in a replacement as$1,$2, and so on.(?: )— a non-capturing group. Same grouping behaviour, but nothing is captured. Use it whenever you are only grouping for the sake of a quantifier or an alternation.(?<year>\d{4})— a named group, read back asmatch.groups.year. Far more readable than counting bracket positions.|— alternation, meaning "or". It has the lowest precedence of anything in regex, so^cat|dog$means "starts with cat, or ends with dog". What you almost certainly wanted is^(?:cat|dog)$.\1— a backreference to whatever group 1 matched.(\w+) \1finds a doubled word.
Lookarounds
A lookaround checks that something is (or is not) next to your match without consuming it — the matched text itself stays out of the result. That is what makes them the right tool for validation rules.
(?=...)— positive lookahead.\d+(?= USD)matches the number in250 USDand returns250, not250 USD.(?!...)— negative lookahead.^(?!.*admin).*$matches any line that does not contain admin.(?<=...)and(?<!...)— the same two, looking backwards. JavaScript allows a variable-length lookbehind; many other engines, Java among them, require a fixed length — so a pattern that runs in the browser can be rejected outright on the server.
Flags
g— global: find every match, not just the first.i— case-insensitive.m— multiline:^and$match at each line break.s— dotall:.also matches newlines.u— unicode mode, required for\p{...}property escapes like\p{Letter}.y— sticky: match only fromlastIndex, never searching forward.
Reading a pattern is much harder than watching one run. Paste any expression from this page into CheckSEO's Regex Tester with your own sample text — every match and capture group is highlighted as you type, entirely in your browser, and nothing is uploaded.
Test a pattern liveThe eight patterns people actually paste
Email address (the pragmatic one)
^[^\s@]+@[^\s@]+\.[^\s@]{2,}$ — one or more non-space characters, an @, a domain, a dot, and a TLD. A fully RFC-compliant email regex runs to thousands of characters and still accepts addresses no mail server will deliver to. Validate loosely, then prove the address by sending a confirmation email — that is the only real check.
URL
^https?:\/\/[^\s/$.?#][^\s]*$ — requires http or https, rejects spaces, and refuses a host that starts with a dot or a slash. For extracting URLs from inside a block of text rather than validating one, drop the anchors and add the g flag.
ISO date (YYYY-MM-DD)
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ — this rejects month 13 and day 32, which the lazy \d{4}-\d{2}-\d{2} version happily accepts. No regex can know that 2026-02-30 is not a real date; that check belongs in your date library.
Phone number (international, E.164)
^\+?[1-9]\d{7,14}$ — an optional plus, then 8 to 15 digits, which is the E.164 maximum. Strip spaces, dashes, and brackets before testing rather than trying to allow every possible way a human might punctuate a number.
IPv4 address
^(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d{2}|[1-9]?\d)){3}$ — long, but it is the only way to enforce the 0–255 range per octet. The popular short version, \d{1,3}(\.\d{1,3}){3}, accepts 999.999.999.999.
Hex colour
^#(?:[0-9a-fA-F]{3,4}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$ — covers #fff, #ffff, #ffffff, and the eight-digit form with an alpha channel. Note that {3,4} and {6} have to stay separate, or you would also accept five- and seven-digit values.
URL slug
^[a-z0-9]+(?:-[a-z0-9]+)*$ — lowercase letters and digits in hyphen-separated chunks. It rejects a leading hyphen, a trailing hyphen, and a double hyphen, which is exactly the shape a clean URL path segment should have.
Password rules
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[^A-Za-z0-9]).{12,}$ — four lookaheads, each asserting one required character class, then a length floor. Because lookaheads consume nothing, they can be stacked in any order. Add or remove a line to change the rules.
The mistake that takes a server down
Nested quantifiers over overlapping character sets — (a+)+$, (\s*\w+)*$, (.*,)* — can force the engine to try an exponential number of paths before admitting failure. This is called catastrophic backtracking, and on a short, deliberately crafted input it will pin a CPU core for minutes. It is a real denial-of-service class, usually written as ReDoS. The fix is almost always to make the inner class more specific so the two quantifiers cannot match the same characters: (?:[^,]*,)* instead of (.*,)*. If a pattern feels slow on a long string in the tester, it is not the tester.
Two places regex will trip you up outside code
Server redirect rules use regex, and the flavour is not JavaScript. Apache's RedirectMatch and Nginx's location ~ both use PCRE, so lookbehind and escaping rules differ slightly — worth knowing when you are writing the 301 rules that move a URL permanently. robots.txt, on the other hand, is not regex at all: it supports exactly two wildcards, * and $, and treats everything else as a literal, which is why a robots.txt rule that looks like a regex so often blocks nothing.
Check it before you ship it
Every pattern above is worth pasting into CheckSEO's Regex Tester with a handful of inputs you expect to pass and a handful you expect to fail. It highlights each match and every capture group live, runs on JavaScript's own RegExp engine, and never sends your pattern or your test text anywhere.
Frequently asked questions
What is the difference between a greedy and a lazy quantifier?
A greedy quantifier like .* matches as much as possible, then backs off until the rest of the pattern fits. Adding a question mark makes it lazy — .*? stops at the first position where the rest of the pattern can match. Greedy matching over a whole line is the most common regex bug.
What is the best regex for validating an email address?
Use a deliberately loose one such as ^[^\s@]+@[^\s@]+\.[^\s@]{2,}$. A fully RFC-compliant email regex runs to thousands of characters and still accepts addresses no mail server will deliver to. Validate loosely in the form, then confirm the address by sending an email to it.
What do the g, i, m, and s flags mean in regex?
g is global — return every match, not just the first. i makes matching case-insensitive. m is multiline, so ^ and $ match at each line break instead of only at the string ends. s is dotall, letting the dot also match newline characters.
What is the difference between a capturing and a non-capturing group?
A capturing group, written ( ), stores what it matched so you can read it back or reuse it as $1 in a replacement. A non-capturing group, written (?: ), groups the same way but stores nothing. Use non-capturing groups whenever you are only grouping for a quantifier or an alternation.
Is regex the same in JavaScript, Python, and PCRE?
The core syntax is shared, but the edges differ. JavaScript allows a variable-length lookbehind where several engines require a fixed length; PCRE has atomic groups and possessive quantifiers that JavaScript lacks; and Python names groups with (?P<name>...) rather than (?<name>...). Always test in the engine you will ship on.
Check your own site with the Regex Tester.
Open Regex TesterMore from the blog
How to Find Your YouTube Channel ID (and Any Other Channel's) in 30 Seconds
How to find a YouTube channel ID three ways: YouTube Studio, the page source, or a handle-to-ID finder. Plus why the @handle is not the channel ID.
Do Hashtags Work on YouTube? What They Do, Where to Put Them, and the 3-Hashtag Rule
Do hashtags work on YouTube? Yes, but not like Instagram. The 60-hashtag limit that voids the whole set, where to place them, and what #shorts does now.