# Regex for Email Validation

> A practical email regex with a token-by-token breakdown, match examples, and why fully RFC-compliant email validation is a losing game.

```
/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
```

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.

## 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 |

## Examples

- ✓ matches: `user@example.com`
- ✓ matches: `first.last@sub.domain.co`
- ✓ matches: `dev+tag@devkult.com`
- ✗ does not match: `plain-address`
- ✗ does not match: `user@host`
- ✗ does not match: `user @example.com`

## 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.

## FAQ

### 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.

## Related patterns

- [Regex for URL Validation](https://www.devkult.com/regex/url.md)
- [Regex for Username Validation](https://www.devkult.com/regex/username.md)
- [Regex for Phone Number Validation](https://www.devkult.com/regex/phone-number.md)

Open the interactive page: https://www.devkult.com/regex/email