How to validate an email address in JavaScript
Everyone wants the regex. The interesting result is what happens when you run the popular one next to the browser’s own check on the same inputs: they disagree on five out of ten.
Three rules, ten inputs
input popular simple browser
"me@example.com" true true true
"a@b.co" true true true
"first.last+tag@sub.example.co.uk" true true true
"üser@example.com" true true false
"me@example" false false true
"me@@example.com" false false false
"no-at-sign.com" false false false
"me@localhost" false false true
"\"quoted string\"@example.com" true false false
"me@[192.168.0.1]" true true false
popular is the RFC-flavoured regex that gets copied out of the accepted
answer, simple is /^[^\s@]+@[^\s@]+\.[^\s@]+$/, and browser is
checkValidity()
on an <input type="email">.
They agree on the first three and the two obvious rejects. Everything else is a fight.
Where they disagree
"üser@example.com" regex=true browser=false
"me@example" regex=false browser=true
"me@localhost" regex=false browser=true
"\"quoted string\"@example.com" regex=true browser=false
"me@[192.168.0.1]" regex=true browser=false
Note the direction: it goes both ways. The regex is not a stricter browser, and the browser is not a looser regex. They are two different rules that happen to agree on the uninteresting cases.
That matters practically, because it kills the plan people usually have — use
type="email" in the form and the same regex on the server. Those two will
reject different users.
The browser is not implementing RFC 5322
me@example and me@localhost are accepted: the browser does not require a
dot in the domain. üser@example.com is rejected, although addresses like it
exist and deliver.
This is not a bug. The HTML specification defines its own e-mail pattern and openly labels it a wilful violation of RFC 5322 — chosen to be implementable and practical rather than complete. So “the browser gets it wrong” is the wrong frame: the browser is following a different, documented rule.
The failure mode that costs you something
real addresses the popular regex rejects:
me@localhost popular=false browser=true
user@[IPv6:2001:db8::1] popular=false browser=false
A regex that lets a typo through costs you one bounced mail. A regex that rejects a real address costs you the user, who now cannot sign up and has no idea why. Those two errors are not equally bad, so the pattern should lean loose.
What actually proves anything
Nothing above tells you the address exists, or that the person typing it can read it. Only one thing does: send a mail with a one-time link and see whether someone clicks it.
So the arrangement that works:
<input type="email" required>in the form — a free client-side check and, on phones, the right keyboard- something loose on the server,
/^[^\s@]+@[^\s@]+\.[^\s@]+$/, to catch the missing@ - a confirmation mail for the actual decision
The regex is a typo-catcher. Treat it as one and it stops being a hard problem.
About Netcup (advertisement)
The German host Netcup offers, among other things, affordable and powerful web hosting packages, KVM-based root servers and dedicated servers. With our voucher codes you can save even more (6€ off your first order, 30% off all KVM-based root servers, ...).