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.

The pattern

^[\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

Copy-paste: Python & JavaScript

# 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());

Test cases your pattern should pass — and fail

✓ should match:
[email protected]
[email protected]   ← the + matters! (below)
[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 track who leaked their address. Forms that reject + are the #1 way developers annoy technical users. The pattern above allows it; keep it that way.
Why not the "perfect" RFC 5322 pattern?
The email spec legally allows quoted spaces, comments in parentheses, and other monstrosities — a truly spec-complete regex runs to thousands of characters and still mismatches real-world mail servers. Meanwhile the only proof an address works is mail arriving at it. So: simple pattern (catches typos) + confirmation email (catches everything else). Spec-lawyering a regex is effort spent on the wrong layer.

Extracting emails from text (different job!)

# unanchored + word boundaries — finding, not validating:
[\w.+-]+@[\w-]+\.[\w.-]+

re.findall(r"[\w.+-]+@[\w-]+\.[\w.-]+", big_text)
# validation = anchored ^...$. extraction = unanchored. never mix.
📚 One page of our regex series. The five concepts, the greedy trap, and when to decline regex entirely — with audio: Regex in 10 Minutes →