TL;DR: Stack Overflow's (and Stack Exchange's) client-side and server-side code rejects valid e-mail addresses, this should be fixed: preferably by only making a basic check, e.g. ^[^@]+@[^.]+(\.[^.]+)+$
(as e-mail address validation with JS is an exercise in futility).
Stack Exchange is the network that tries to
Make the Internet a better place to get expert answers to your questions;
yet, for all the excellent Q&A we have on e-mail address validation, I was horrified when a user uncovered that this site itself uses a horrible, terrible, no good e-mail "verification" regex:
^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$
That thing looked eerily familiar. Indeed, it is the notorious regex from http://www.regular-expressions.info/email.html - which "matches all valid e-mail addresses". Or so the author claims - as he immediately adds that "I consider everything not matched by this to be invalid"; I see that logic as slightly circular, although he does have valid points for choosing that pattern in his specific situation (e.g. "meh, this is just a simple website, why bother with three nines?" and "there's no perfect regex anyway"). Alas, due to the Bathroom Wall Of Code effect, this regex found its way into various collections of "useful regexes" and thence to SO. Unfortunately, it seems that the various regex snippet libraries only disclose the first part of @Jan Goyvaerts' assertion ("matches all valid e-mail addresses"), without highlighting the tradeoffs and pitfalls of this snippet (which the author discusses in quite some depth on the aforementioned page).
Now, there's a lot of discussion and controversy on "the right way to validate e-mail addresses", and I think e.g. this question addresses the technical parts excellently; but on top of that, amongst my issues with this particular usage are:
- a small site somewhere on the Net can get away with "I'll just reject your e-mail address because **** you, it's my site, now go away already"; that is an inappropriate approach for Stack Exchange.
- the regex is outdated and inaccurate, what with the new(ish) IDNs and ancient outliers such as
.travel
and.museum
. - and worst of all, it gives a bad, you could even say hypocritical, example: "do as we tell you, not as we do" - it is rather awkward to explain to people that no, this is a bad way to validate e-mails, on the same site which uses that code - see the comments under this question. Also, we're actively contributing to the Bathroom Wall of Code effect ("Can we make a search-and-replace on the entire Internet? ... Oh.").
Let me quote from Validate an E-Mail Address with PHP, the Right Way:
There is some danger that common usage and widespread sloppy coding will establish a de facto standard for e-mail addresses that is more restrictive than the recorded formal standard.
Do we want to be seen as perpetrators (propagandists even, as this is a network of sites for learning) of such "sloppy coding"? Such false negatives when validating addresses are the e-mail's equivalent of "all text is ISO-8859-1", IMNSHO.
So, I have three suggestions of variable insanity:
- If there is a need (or an urge) to validate e-mails in JavaScript, since this check is only done once in a while, and then only when notification checkbox changes state (if I understand this correctly), the full ex-parrot regex would be useful
- Should the SE team see this as overkill, I'd suggest making this a sanity check only - if it doesn't pass the (possibly too-strict) regex, ask user if xe really wishes to use that address, but don't prevent it.
Note that I wrote "If there's a need (or urge)": I don't think that it's possible to determine in JavaScript whether something is a valid e-mail address - it is possible to determine that something is not a valid e-mail address, but even well-formed e-mail addresses are not guaranteed to be valid: piskvor@example.com
passes even the most restrictive tests, yet I doubt you would reach me there. JS e-mail address validation may have been easier in 1998 (without all those pesky newfangled 4+ letter TLDs and whatnot), but in 2011, it's an exercise in frustration and futility - in fact, I would even call it cargo cult programming: most people implement it because "must have JS e-mail validation, everyone else has it" - without any real benefits from what often becomes a misfeature.
- So, by @Pekka's suggestion, and with the help of this question, I propose only checking for
@
(and possibly a 2nd+ level domain name, but then it gets complicated again with IDNs and whatnot), and leaving the rest to the mail transfer agents - after all, those implement a parser for what is and what isn't an e-mail address (one would hope).
Edit: Like using MD5 for security, the problem isn't getting magically better by ignoring it. Quite the contrary, it's getting worse: Apart from the parallel IDN gTLD program, ICANN has recently (June 2011) announced golden-rule*, free-for-all gTLDs. If you think that excluding .travel
is good policy because who cares, will it take something like .apple
getting registered? This is - as of now - only a possibility, but it's another nail into the \.[a-z]{2,4}$
's coffin.
*The other golden rule obviously, as the vanity gTLDs will be quite expensive.
Edit 2: Oh dear. Apparently the regex lives in SO/SF/SU/SE's server side code as well - see the screenshot, complete with freehand circles. From this, I infer that there's another place in the code which assumes \.[a-z]{2,4}$
is correct. This is getting kind of silly.
*@*
silly anyway? What is it good for in the first place? I've never really understood that, and can't see any arguments for it e.g. here - How far should one take e-mail address validation?kaegkljklgioagioui@jkaseguiuiargjha.weiorhasper.guieprgeas.sdgkaeguiwssdhusd.com
,which is invalid (but good luck checking that in JavaScript )