No regex can tell you whether an email address will receive mail — only whether a string is shaped like one. If you need a working pattern right now, /^[^\s@]+@[^\s@]+\.[^\s@]+$/ rejects the obviously broken input (missing @, missing domain, embedded whitespace) without rejecting real addresses that use plus-addressing, subdomains, or non-English characters. It does not confirm the mailbox exists — nothing built from regex can. That is the honest answer to "regex for email validation," and the rest of this page explains why the patterns you'll find elsewhere get it wrong.
Paste any pattern below into our Regex Tester and run it against your own list of edge-case addresses as you read — everything runs in your browser, so nothing you paste leaves your device.
The textbook pattern, and the four things it silently rejects
Search for "email regex" and you'll mostly find some variant of this:
^[\w.-]+@[a-zA-Z0-9-]+\.[a-zA-Z]{2,4}$It looks thorough — character classes, a length-bounded TLD, anchors on both ends. Tested against real addresses, it fails on exactly the ones your users actually have:
user@example.com → matches
user+newsletter@example.com → rejected (plus-addressing)
user@mail.corp.example.com → rejected (subdomain)
user@example.technology → rejected (TLD longer than 4 chars)
müller@example.de → rejected (unicode local part)Each rejection traces to one specific design choice. \w expands to [A-Za-z0-9_] — no +, so plus-addressing (a real, widely-supported Gmail/Outlook feature people use for filtering) fails outright. The domain half, [a-zA-Z0-9-]+\.[a-zA-Z]{2,4}, allows exactly one label before the TLD — no dot permitted inside it — so any subdomain (mail.corp.example.com) or compound TLD (example.co.uk) breaks it. The {2,4} bound on the TLD is a holdover from when TLDs were .com/.org/.info-length; it silently rejects every newer gTLD longer than four characters — .technology, .photography, .consulting. And \w without a Unicode flag only matches ASCII, so any local part with an accented or non-Latin character fails, even though RFC 6531 (SMTPUTF8) and every major mail provider have supported Unicode addresses for years.
The other extreme: a pattern so loose it stops meaning anything
The usual overcorrection is to loosen the character classes until almost anything passes:
^\S+@\S+\.\S+$This one does accept plus-addressing, subdomains, long TLDs, and unicode — it's permissive enough to match real-world addresses correctly. But permissive cuts both ways:
user@@example.com → matches (double @, not a valid address)
user@example → rejected (no dot in the domain — see the HTML5 section below for why this same input is valid there)\S means "not whitespace," and @ is not whitespace, so a second @ slides right through. A pattern this loose isn't really validating structure at all — it's just confirming the string contains an @ and a dot somewhere. Looseness alone isn't correctness any more than strictness is.
Why nobody actually uses the RFC 5322 regex
RFC 5322 defines the real email address grammar, and it's far larger than either pattern above. It legalizes quoted local parts ("john..doe"@example.com), comments inside addresses, folding whitespace, and literal IP-address domains (you@[192.168.1.1]). A regex that fully implements this grammar is a famous artifact — commonly quoted at around 6,300 characters, built from dozens of nested non-capturing groups. It is not something a human reviews, debugs, or maintains with confidence, and running it against user input on every form submission is real, avoidable backtracking cost for a validation step that doesn't need it.
It also solves a problem you don't have. It correctly matches addresses that are technically legal under the spec but that no real mail provider issues to a real user. Matching RFC 5322 exactly proves an address is syntactically legal mail-grammar — it does not prove the address is one a person would ever actually have, and it does not get you closer to knowing whether the address works.
What HTML5's type="email" actually checks
Before reaching for a JavaScript regex at all, most forms should reach for this first:
<input type="email" required>Every browser validates it for free, against the pattern the WHATWG Living Standard specifies — no JS, no bundle size, and it shows the browser's native inline error UI automatically. Two things about it surprise people who assume it's a stricter check than it is:
- It has the same unicode gap as the naive regex above — a local part like
müller@example.defails HTML5 validation unless the browser applies IDNA punycode conversion first. - It does not require a dot at all.
user@examplepasses — the spec intentionally allows single-label domains, since intranet and local mail setups are legal use cases the standard doesn't want to exclude.
You can tighten it with the pattern attribute, but at that point you're back to writing the same regex trade-offs described above — just inside an HTML attribute instead of JavaScript. Use type="email" as your free first line of defense either way; it costs nothing and covers the common typos (missing @, missing domain) before any of your own code runs.
A pattern worth actually keeping
If you need a client-side regex beyond what type="email" gives you, this is the one to reach for:
^[^\s@]+@[^\s@]+\.[^\s@]+$It rejects a missing @, a second @, embedded whitespace, and a missing dot — the genuinely malformed cases — while correctly accepting plus-addressing, subdomains, compound TLDs, and unicode local parts:
user+newsletter@example.com → matches
user@mail.corp.example.com → matches
user@example.co.uk → matches
müller@example.de → matches
user@@example.com → rejected
user@ example.com → rejected
user@example → rejectedIts trade-off: it doesn't enforce a specific TLD list or reject the handful of legal-but-vanishingly-rare RFC 5322 forms (quoted local parts, IP-literal domains). For almost every form on the web, that trade-off is the right one — it's the same "reject obvious garbage, don't reject real users" balance a production signup form actually wants. Drop it into the Regex Tester against your own address list to confirm it fits your case before you ship it.
The honest conclusion: regex can't confirm a mailbox exists
None of the patterns above — not the textbook one, not the loose one, not RFC 5322, not HTML5's own check — can tell you whether user@example.com actually receives mail. A syntactically perfect address can still be a typo (user@gmial.com), a mailbox that was deleted last year, or a domain with no mail server configured at all. The only way to know is to send a message to it and see whether a person can act on it — a confirmation email with a click-to-verify link. That undercuts the premise of the search that brought most readers here, but it's the actual answer: treat regex as the free, instant rejection of obviously malformed input before you bother sending that message, not as the validation step itself.
Frequently asked questions
What's a good regex for validating an email address?
^[^\s@]+@[^\s@]+\.[^\s@]+$ — it rejects a missing @, a second @, whitespace, and a missing dot, while still accepting plus-addressing, subdomains, and unicode local parts. It won't catch every theoretically-invalid RFC 5322 edge case, and it can't confirm the address actually receives mail — nothing built from regex can.
Why does my email regex reject addresses like user+tag@example.com?
Almost always because the local-part character class is \w or an explicit [a-zA-Z0-9._-] list — neither includes +. Plus-addressing is a real, widely-supported feature (Gmail, Outlook, and most providers route on everything after the +), so a pattern that excludes it is rejecting valid users, not catching bad input. Add + to the character class, or switch to a pattern like [^\s@]+ that only excludes whitespace and @.
Should I use the RFC 5322 regex for email validation?
No. It's roughly 6,300 characters of nested groups, expensive to run on every form submission, and it correctly matches address forms (quoted local parts, IP-literal domains) that no real mail provider issues to actual users. Full RFC 5322 conformance proves an address is syntactically legal mail grammar — it doesn't prove it's an address a person has, which is the thing you actually care about.
Is HTML5's type="email" enough on its own?
It's the right first line of defense — free, built into every browser, zero JS — but not sufficient by itself. The spec doesn't require a dot (single-label domains are legal), and it doesn't validate unicode local parts without punycode conversion. Pair it with server-side handling and, for anything that matters, a confirmation email — that's the only check that proves the mailbox is real.
For the full regex syntax — quantifiers, lookaround, flags — see our Regex Cheat Sheet. If you're building or debugging patterns beyond email, our regex testing guide covers the general workflow — building incrementally, testing edge cases, and avoiding catastrophic backtracking — that applies to any pattern, not just this one.