Regular expressions have a reputation for being unreadable, and a pattern like ^(?=.*[A-Z])(?=.*\d)[A-Za-z\d]{8,}$ earns it. But regex is not one thing to learn; it is about fifteen small pieces that combine, and most real tasks use four or five of them. This guide teaches the pieces in the order you will need them, with a pattern for each of the jobs people actually search for, and the habit that makes regex safe to use: test every pattern against real input before it goes anywhere near production.
The pieces
| Syntax | Matches | Example |
|---|---|---|
abc | Literal text | cat matches “cat” in “concatenate” |
. | Any single character except newline | c.t matches cat, cot, c9t |
\d \w \s | Digit, word character (letters, digits, _), whitespace | \d\d\d matches 123 |
[abc] [a-z] [^0-9] | Character class; range; negated class | [aeiou] matches any vowel |
* + ? | Zero or more; one or more; zero or one | colou?r matches color and colour |
{3} {2,5} {2,} | Exactly 3; 2 to 5; 2 or more | \d{4} matches a 4-digit year |
^ $ | Start and end of line/string | ^Hello only at the start |
\b | Word boundary | \bcat\b matches “cat” but not “concatenate” |
(…) | Group, and capture | (\d{2})/(\d{2}) captures day and month |
a|b | Alternation (or) | jpg|png|webp |
\. \? \( | Escaped special character | \. matches a literal dot |
That table is most of regex. Paste any pattern below into the Regex Tester alongside sample text and it highlights every match, shows the capture groups, and updates as you type, which is the only sane way to build a pattern.
Patterns for common jobs
Email (practical, not RFC-complete)
^[\w.+-]+@[\w-]+\.[\w.-]+$ Matches nearly every real address and rejects obvious junk. A fully RFC-compliant email regex is 6,000 characters long and still lets through addresses that don’t exist; validate the shape here and confirm by sending an email.
URL
^https?://[\w.-]+(?:\.[\w.-]+)+[\w\-._~:/?#\[\]@!$&'()*+,;=%]*$ Phone number (international, loose)
^\+?[\d\s()-]{7,20}$ Phone formats vary too much for a strict pattern. Strip everything except digits and +, then check length.
Date, YYYY-MM-DD
^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01])$ Checks shape, not calendar validity; it will accept 2026-02-31. Parse with a date library for that.
Password: 8+ chars, one uppercase, one digit
^(?=.*[A-Z])(?=.*\d).{8,}$ The (?=…) groups are lookaheads: they assert something exists without consuming it, which is how you check multiple conditions on the same string.
Extract hashtags
#\w+ Find duplicate words
\b(\w+)\s+\1\b \1 refers back to the first capture group, so this finds “the the”.
Trim whitespace at line ends
[ \t]+$ Replace with nothing. Works in any editor with regex find-and-replace.
Greedy vs. lazy: the bug everyone hits
<.+> against <b>bold</b> matches the whole string, not just <b>, because + is greedy: it grabs as much as possible and backtracks only if forced. Add ? to make it lazy: <.+?> matches <b> and </b> separately. Whenever a match is longer than expected, this is the first thing to check.
Flags
i— case-insensitive./cat/imatches Cat.g— global. Find all matches, not just the first. Essential for replace-all.m— multiline.^and$match at each line, not just the string ends.s— dotall..also matches newlines.
Dialects
Everything above works in JavaScript, Python, PHP (PCRE), Java, Go and most editors. Differences to know: Python uses (?P<name>…) for named groups where JavaScript uses (?<name>…); POSIX tools like grep without -E need \+ and \? escaped the other way; and lookbehind (?<=…) is unsupported in some older engines. The tester uses JavaScript’s engine, which is the most common target.
Three rules for using regex safely
- Test with real data, including the cases that should not match. A pattern that matches everything looks like it works.
- Anchor it. Without
^and$, a validation pattern matches a substring, so\d{4}“validates” the string “abc12345”. - Prefer a parser for structured formats. Regex for HTML, JSON or CSV breaks on the first edge case. Use the JSON Formatter or a real parser; keep regex for text.
Frequently asked questions
What is the regex for an email address?
A practical one: ^[\w.+-]+@[\w-]+\.[\w.-]+$. Fully correct email validation is not possible with regex alone; confirm by sending a message.
Why does my regex match too much?
Usually a greedy quantifier. Change .+ or .* to .+? or .*?.
How do I match a literal dot or question mark?
Escape it with a backslash: \., \?. Inside a character class [.] the dot is already literal.
Is regex the same in every language?
The core is. Named groups, lookbehind and some escapes differ. Test in the engine you will deploy to.
Free, runs in your browser, nothing uploaded, no sign-up.
Keep reading
More from Developer & Code Tools.
Tools for this job
Free, in your browser, no sign-up.


