Regex for Email Validation
This is the pragmatic email pattern: printable local part, @, a domain with at least one dot, and a two-plus letter TLD. It accepts every address your users will realistically type and rejects the obvious garbage. Full RFC 5322 validation needs a parser, not a regex — the only real test of an email address is sending mail to it.
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/How it works, token by token
| Token | Meaning |
|---|---|
| ^ | start of string — nothing before the address |
| [a-zA-Z0-9._%+-]+ | the local part: letters, digits, dots, and common symbols, one or more times |
| @ | the literal @ separator |
| [a-zA-Z0-9.-]+ | domain labels: letters, digits, dots, hyphens |
| \. | a literal dot before the TLD (escaped — a bare . matches anything) |
| [a-zA-Z]{2,} | the TLD: at least two letters (com, io, dev …) |
| $ | end of string — nothing after the address |
What it matches
user@example.comfirst.last@sub.domain.codev+tag@devkult.complain-addressuser@hostuser @example.comTry it live
One candidate per line — the m flag makes the ^ and $ anchors apply to each line. Edit anything; it runs in your browser.
Variations
^[^\s@]+@[^\s@]+\.[^\s@]+$looser: anything without spaces or extra @ signs — fewer false rejections, more junk accepted^[a-zA-Z0-9._%+-]+@example\.com$restrict to a single domain (replace example.com)Language notes
- Python: use re.fullmatch(pattern, s) and you can drop the ^ and $ anchors.
- Go: works as-is with regexp.MatchString — no lookaheads involved, so RE2 is fine.
Frequently asked questions
Why not validate emails strictly to the RFC?
RFC 5322 allows quoted local parts, comments in parentheses, and other forms no user ever types. A fully compliant regex runs to thousands of characters and still can't tell you whether the mailbox exists. Validate the shape loosely, then confirm by sending a verification email.
Does this pattern accept unicode domains?
Not directly — internationalized domains arrive punycoded (xn--…), which this pattern accepts. If you need raw unicode local parts or domains, add the u flag and widen the character classes, or normalize to punycode first.
Building something custom? The regex tester gives you live match highlighting for any pattern.