Regex for email validation

The short answer, then the honest context: the pattern below catches typos, and a confirmation email catches everything else. That combination is what production systems actually do.

🎙️ Published & recorded: ·

The pragmatic email pattern

This pattern checks the useful shape: some allowed characters, one at sign, a domain, and a suffix after a dot. It is deliberately a typo filter, not a proof of delivery. Match the whole input so a valid-looking fragment cannot rescue surrounding junk.

^[\w.+-]+@[\w-]+\.[\w.-]+$

# read it: one-or-more of [letters/digits/_/./+/-]  @
# domain chunk  .  rest of domain (dots allowed)
# anchored ^...$ because validation must match the WHOLE string

Python, JavaScript, and the tests that matter

Trim accidental outer whitespace, then run the same whole-string check in either language. Keep a short test list beside the pattern. Positive tests protect real addresses such as tagged inboxes, while negative tests catch missing pieces, spaces, doubled separators, and extra at signs.

# Python
import re
EMAIL_RE = re.compile(r"^[\w.+-]+@[\w-]+\.[\w.-]+$")
def looks_like_email(s):
    return bool(EMAIL_RE.match(s.strip()))

// JavaScript
const EMAIL_RE = /^[\w.+-]+@[\w-]+\.[\w.-]+$/;
const looksLikeEmail = s => EMAIL_RE.test(s.trim());
✓ should match:
[email protected]
[email protected]
 [email protected]

✗ should NOT match:
ada@example        (no TLD)
@example.com       (no local part)
ada @example.com   (space)
ada@@example.com
"ada"@example..com
Don't reject the plus sign
[email protected] is valid and deliberate. People use tags to sort mail and identify leaks. A form that says “Please enter a valid email address” for a tagged address is broken; keep the plus sign in the allowed set.

Validation, confirmation, and extraction

Do not build the enormous standards-perfect pattern. Mail systems disagree at the edges, and syntax cannot tell you whether an inbox exists. Use the short check to catch obvious mistakes, then send a confirmation message. When finding addresses inside prose, use the same core shape without requiring it to occupy the whole string.

Why not the “perfect” RFC 5322 pattern?
The specification allows quoted spaces, comments, and other rare forms. A complete-looking regex runs to thousands of characters and still cannot prove the mailbox works. The concrete production fix is simple validation followed by a confirmation link; do not turn account signup into a standards-lawyer contest.
# unanchored — finding, not validating:
[\w.+-]+@[\w-]+\.[\w.-]+

re.findall(r"[\w.+-]+@[\w-]+\.[\w.-]+", big_text)
# validation = anchored ^...$. extraction = unanchored. never mix.
A real failure symptom
If a validator accepts noise [email protected] noise, it is searching instead of validating. Require a full-string match. If an extractor returns nothing from a paragraph, check that you did not reuse the anchored validation pattern.
📚 One page of our regex series. The five concepts, the greedy trap, and when to decline regex entirely — with audio: Regex in 10 Minutes →

Tell me what missed

A correction is more useful than a compliment. This goes straight to the person who writes SwiftGrasp.

Was this page useful?
0/1000

Please do not include passwords, private keys, or personal information.