breakitdown

Regex for an email address

Answer

Use ^[^\s@]+@[^\s@]+\.[^\s@]+$: one or more non-space, non-@ characters, an @, then a domain with at least one dot. It catches typos like a missing @ or a stray space. Then prove the address works by sending a confirmation email.

flags: g all matches · i ignore case · m ^ $ per line · s . matches newlines · u Unicode

JavaScript ✓PCRE ✓

Slow on long input. [^\s@]+ and [^\s@]+ can match the same characters, and what lies between them can be matched by the first one too. On a long string that fails to match, the engine tries every split point: quadratic time. Harmless on short input, a risk on long untrusted input. Make the first part unable to match what follows it (for example [^.@]+ instead of [^@]+ before \.), or limit the input length before matching.
  1. ^Start of the stringanchor
  2. [^\s@]Any one character except a whitespace character (space, tab, line break and other Unicode spaces) and '@'character class
  3. +Repeat the class one or more times, as many as possible (greedy)quantifier
  4. @The character '@' literallyliteral
  5. [^\s@]Any one character except a whitespace character (space, tab, line break and other Unicode spaces) and '@'character class
  6. +Repeat the class one or more times, as many as possible (greedy)quantifier
  7. \.The character '.' literallyliteral
  8. [^\s@]Any one character except a whitespace character (space, tab, line break and other Unicode spaces) and '@'character class
  9. +Repeat the class one or more times, as many as possible (greedy)quantifier
  10. $End of the stringanchor

Examples

Checked at build time in JavaScript and in Python's re.

InputMatches?
user@example.com✓ match
first.last+tag@sub.example.co.uk✓ match
o'brien@example.ie✓ match
no-at-sign.example.com✗ no match
user@localhost✗ no match
two words@example.com✗ no match
user@@example.com✗ no match
a@b.c✓ match
user@example..com✓ match
user@.example.com✓ match

Try your own text

One string per line: each line is tested on its own (the m flag is added here).

How it works

The full grammar in RFC 5322 allows quoted local parts ("john doe"@example.com), comments in parentheses, and IP-literal domains (user@[192.0.2.1]). A regex that covers all of it runs to thousands of characters, and it still cannot tell you whether a mailbox exists. The only real test is a message the user receives and clicks.

So the job of the regex is a sanity check: reject input that is obviously not an address, and accept everything a real mail server might take. A pattern that is too strict is worse than one that is too loose. It turns away real customers with addresses like o'brien@example.ie or user+tag@example.com.

Browsers have their own check. An <input type="email"> validates against a pattern from the HTML standard (shown below under variants). It is deliberately simpler than RFC 5322: it does not allow quoted local parts, and it accepts a domain with no dot, such as user@localhost.

Variants

Gotchas

Related explainers

← Explain any regular expression