No, no, no, no. Normal people don’t always use the email field properly. The might put the username in the email field and the email in the username. Just check for an @. There is no email in the world outside your server that you can sent to without an @.
I did that for a time (which I mention in the article), but it's still a superfluous check on top of an activation email. If your users are typing the wrong values into your registration form, perhaps you need better labeling or placeholder text? Display an error that the activation email couldn't be sent. But why add superfluous checks?
Yes, agreed (and I mention this at the end of the article as well) and I still use the /@/ regex often. But a good UI on the registration form can go a long way in alleviating the "switching the email address and username fields" problem.
Often, your web server application won't know that the activation email can't be sent. It's common practice to throw outgoing emails into a job queue, so a very basic check isn't superfluous at all.
Yep, this is definitely most often the case. Perhaps I should have reworded that to reflect that I believe anything more than a simple /@/ check to be largely superfluous. I still use the /@/ regex often, which I mention at the end of the article.
While I appreciate the elegance of your solution from an engineering perspective the user who accidentally enters an invalid address is definitely getting a worse user experience here. If you're using javascript to validate the email a user will know they've made a mistake immediately. In your scenario they'll see a page telling them that they should receive an email, and then what? They have to start again? If they're lucky they'll think of hitting the back button and full it in correctly. More likely, they'll just think; hmm this email's taking a while to come through, I'll check Facebook... With a bit of luck they'll remember they were trying to sign up for your service, otherwise, you just lost a signup.
Yes exactly. We validate client side using typical JavaScript, and we also validate server side.
In our case, accounts may be created by third-party apps using REST JSON APIs, so we want to let the third-party app know that the email address isn't RFC-valid.
I am chose my phrasing for the very reason that it's merely incredibly unlikely and not at all impossible. I've even sent mail with bang-paths post-2000 just to confound the recipient, though it is a rare network that would accommodate that today.
Nowhere that I know of, at least not for certain. The company with the mail server I used has been subsumed by another company, however some other companies from that time may still be running compatible mailers.
I totally agree. The one other thing I might add is to check for commas, since they are never valid in an email address and "something,com" is a common typo.
You've got it backwards-- the use case is to catch things like "grandma@aol" and "foo@@bar,com". If we just check for "@" then we'd send email into the void. Instead, we check for more specifics, and we prompt the user to correct the email address. This improves our response rate about 2% which for us is significant.
Here's another thought, just off the top of my head: get people to sign up by sending an email to "subscribe@example.com". You can include that as a "mailto:" link and many browsers will deal with it correctly.
There's very good odds that the email they send will have their "From:" (or "Reply-To:") address correctly set. Then just have an email autoresponder which emails them back a link with a token in it, when they click on that it'll take them to a page to create their account, with their email address already filled in by the token.
Yeah, maybe. But you're going to have to send them there some time to do the "confirm email" thing, I was just thinking perhaps get that over and done with upfront.
Ideally, all this would be done away with by OpenID or client-side certificates or something along those lines. The whole password-and-email-in-case-you-forget-it paradigm is broken, really.
That's not true either. I don't know how it's set up other than that we use exchange, but on our internal network, you can send an email to someone's firstinitiallastname (the part that is before the @ for external senders) and it will go through.
So on our production servers, I need the @, but on our dev/text servers, I don't. And no, the domain is not appended to the address before sending. That's the part I actually know about.
It's common practice to allow unqualified emails addresses (ie. without the @domain.tld) from local sources since it's trivial to look up against your own user list. Depending on the MTA, the domain may or may not be appended, but often the local organisation's default domain is implied. However, this shouldn't work when routing mail via external MTAs that have no knowledge of your organisational structure.
This guy doesnt "get" UI. You are supposed to protect the user from additional steps/mistakes,and not protect your service from the user when you use regex to validate the email. Otherwise users could perfectly fool your best system using billgates@microsoft.com
I think saying that I don't "get" UI is being somewhat presumptuous. Good UI on the registration form can go a long way in alleviating the "switching the email address and username fields" problem, but anything more than a check for /@/ (or, if you're feeling ambitious, /.+@.+\..+/) is just overkill. If I enter a valid email address that's just typo'd, the result is the same: the activation email bounces.
>If I enter a valid email address that's just typo'd, the result is the same: the activation email bounces. //
No, you're excluding the set of emails that are entered incorrectly and thus are not valid. The result for those is not the same as if the UI included a simple test (such as your "ambitious" example).
1) Without UI validation:
- 1.1) Email address entered correctly -> activation email sent
- 1.2) Email address entered incorrectly but forms a valid address -> activation email sent to wrong address
- 1.3) Email address entered incorrectly but doesn't form a valid address -> activation email not sent
2) With UI validation:
- 2.1) Email address entered correctly -> activation email sent
- 2.2) Email address entered incorrectly but forms a valid address -> activation email sent to wrong address
- 2.3) Email address entered incorrectly but doesn't form a valid address -> user warned
-- 2.3.1) Email address re-entered correctly -> activation email sent
-- 2.3.2) other states
In the 1.3 case all of the activation emails fail to be sent. In the 2.3.1 case activation emails are sent that otherwise wouldn't be.
Sorry, yes, this wasn't supposed to be exhaustive just to illustrate the point that not providing a warning on apparently erroneous email address entries was some what pathological.
/.+@.+\..+/ would be a bit too ambitious as the dot is not necessarily part of a valid email - an MX record can appear on a TLDs DNS records[1]. Considering ICANNs new licensing of hundreds of TLDs this could be a very real concern soon.
I think the point is that in reality the user should be protected from the service -- which may be trying to validate their input and telling them their perfectly valid email address (or address, postal code, name, password) cannot possibly exist.
A better way is to check that the email the user entered matches a typical email format, and if the email doesn't match, then warn the user that he/she might've entered the wrong email address (for example writing foobar@gmail, or foobar@gmail.com.).
A few years ago I would have agreed, and I still do in general. But now I'm not sure that Perl grammars aren't up to the task and still as 'regular' as PCRE.
However you still shouldn't be writing your own unless you're writing an email validation module of some kind. Laziness is a virtue after all.
I've been thinking about service that injects some lines of javascript for client sites that gives them button "fix this". It would send warning email after few messages about typos but it could also be used to fix these kind of things. Not sure how JS could handle selection and button press simultaneously. Maybe copy+paste part of page with fix. Maybe get some reward for being grammar nazi. Maybe some paid service for auto checking if corrections are accurate and auto-inject corrections to sites.
I'd like to think that's not rare enough for websites to have assumed they were always six characters - half of London lives in postcodes like "N1 2BC". The bigger problem I've found with postcodes was sites insisting on five digits, or even insisting on postcodes at all - not every country uses them!
Although I agree with the meta-point, there's still value in doing some basic validation. If there's no @ sign, or the domain name looks like it was mistyped (gmali, yahhoo), then a better user experience for your user is to present them with a warning and ask them to retype their email. You may not want it to be a blocking warning (that is you can still submit the form), but some validation can be a huge value add to users.
Still, sending an email beats regex validation any day for determining it's a real, working address.
Yeah, skip all that too. Who says yahhoo.com isn't a valid domain?
For example, I regularly receive email for an individual who has a nearly identical email address to my own, but at ymail.com instead of gmail.com. Any system that tries to guess at domain misspellings is going to catch ymail.com and think "Ah ha, they meant to type gmail.com, I'll correct that for them!" Viola, their email is sent to me. Again, this is not a theory, it happens to this poor guy all the time.
At work I've introduced mailcheck.js[1] (which I found on HN, BTW.) and we use it in registration form to give hints about mistyped popular polish and international domains. We do also have some validation code, but it's simple and it handles + sign correctly. It's important not only for users, but essencial for developers as well - right now I have 56 unique accounts on the development server using the same e-mail but different things before the + sign. It helps tremendously.
If your service tells me that myname+servicexyz@gmail.com is an invalid address, you have to live without me. I can't count how many mails I sent to websites incorrectly validating email fields. However, password validation is mostly even worse. Just stop over-validating already!
Agreed that password validation is the worst. (Github, I'm looking at you.)
Even worse than excessive validation is when they make you change your password often, for no apparent reason.
On some sites that do both (ahem Apple), the only way I can login if I haven't been there in awhile is the security questions or the password reset mechanism.
Wow, I never noticed that Github enforces password rules, as well (Must contain one lowercase letter, one number, and be at least 7 characters long.). My passwords are usually HMAC-based, so they'll most likely validate.
even validation of first & last names is usually awful. For instance many sites tell you that having a dash "-" in your first name is invalid... yet a lot of French (first or last) names contain that character..
Those who happen to own domain name and some small hosting plan with Cpanel can easily redirect all mail to that domain for specific email address. This way you can replace plus sign with dot that works everywhere.
Guys, I have to interject. This is a terrible idea:
This is horrible practice from the perspective of a mail server. Too many illegitimate email addresses and you will start getting more "soft bounces" (a polite way to say, "We're not delivering this") when attempting to send mail. ISP's keep score for how accurate a mail server is when delivering mail, attempting to sift out spammers. When your score dips to a certain level, ISP's stop cooperating with you and basically label you as a "dubious/bad actor".
For a small-scale operation, perhaps this is okay. For anything larger or more vital, I wouldn't trust this method of operation, as it will at some point result in emails to legitimate addresses not being delivered. That's simply unacceptable for many applications.
If you get an incorrect address, it's because the user made a mistake. Chances are, most of those mistakes will still be RFC-compliant addresses (wrong or missing letters, for example). I find it hard to believe that people inputting addresses without @s or with unicode characters would become a real problem.
Frankly, your lack of belief is likely due to a lack of experience with user submitted forms with email addresses. It's VERY common for users to simply type the wrong data into a particular textarea. If you do no validation you will get things like the person's name, street address, or other confused mixups.
Anyone who deals with forms of this nature will have seen this firsthand, and with enough frequency to cause trouble with mail relay as the person above has described. It's a real problem.
The biggest argument for not validating email addresses shouldn't be that "it's hard". It should be that email providers don't always follow RFC guidelines. At my old job, we had this really weird bug that, after a lot of work, we tracked down to users who legitimately had greek letters in their email addresses.
If there are legitimate emails that don't follow RFC, you should absolutely allow users to enter non-RFC-compliant email addresses.
It's not hard, though. Anybody can go online and search for an email validating regex, but as some have pointed out, many are too strict and don't allow for, say, tagged email addresses (email+tag@example.com). There's email validation, and there's overkill. That's what I was trying to get at.
The difficulty of writing regexes for email validation wasn't the main point - the main point was that emails don't follow spec so any regex based on that is inherently wrong. However, it seems like saying "most email validation regexes are broken" is equivalent to saying "email validation regex is hard"
A couple years ago Evan Phoenix (of rubinius) and I collaborated (by which I mean he wrote the grammar and I did almost nothing) on a REAL RFC compliant email address validator using a PEG for parsing: https://github.com/larb/email_address_validator
I don't know that anyone uses it, or would even want to use it. It was a fun project, but I certainly wouldn't use it in an app (unless it was an MTA or MUA). What comprises a valid email address is way too broad.
I think there are reasonable regexes for email addresses FWIW. The RFC(s) are stupid and broken, and you can hit 99.99999% of addrs and provide useful errors back to the users with a regex.
We use a combination of client-side JavaScript validation and server-side validation in Rails. Typical server-side validation is for REST JSON API calls by third-party apps, and also for parsing freeform text fields like "tell your friends about us".
Sure, I mean `me@yahoo` is an RFC-compliant email address, it refers to a local server 'yahoo'. However in your online app it's almost certainly an error if this email address turns up in a registration form.
Don't test for an RFC-compliant address if you don't want to accept all RFC-compliant addresses. Being able to send an email is a much better test because it matches what you're going to use the email address for in your app.
But your way, if the user makes a typo like "foo@@bar,com" then he will expect to receive an email but wont. Better UX in my opinion is to do validation before sending, both client-side and server-side (esp. good for REST JSON APIs), then if these are all good send the welcome email.
I wouldn't mind using a simple regex or validator to check the e-mail addr for validity.
It wouldn't be RFC-compliant, but it would catch 99% of typos.
Instead of being an error when the e-mail fails validation though, it would say something like: "your e-mail does not appear valid; please double check your entry. You will be sent an activation e-mail; click [Continue] if you're sure the address is valid."
Basically if it fails the "99%" test, then if that fails, let the user decide if their e-mail is in the 1% or not.
I see that the API you feel most people would want is validate_2822_addr (aka validate_addr), which validates an addr-spec (as people should really not be typing angle addresses with display names into forms asking for their e-mail address ;P).
However, that specification, and the implementation you provide, is really designed for parsing e-mail address headers (as you say: for an MTA/MUA), and so contains a bunch of properties specific to structured MIME fields that really has nothing to do with e-mail addresses.
Instead, if you are verifying an e-mail address that someone types into a form, you probably are looking for "the kind of e-mail address that SMTP would accept for delivery", and that is covered by a different standard with a different and unrelated grammar.
Specifically, you implemented RFC 2822, the successor to RFC 822 that has now been obsoleted by RFC 5322, the standard on "Internet Message Format" (in essence, MIME). The related RFC 2821, the successor to RFC 821 that is now obsoleted by RFC 5321, is for SMTP.
For an example of the kinds of differences this would cause, RFC 5322 (with errata) believes that ""@example.com is invalid (by errata), but hello(ignore)@example.com is (MIME comment); RFC 5321, on the other hand, believes the exact opposite validity.
(edit: When I realized that I should probably write a blog post about this, given how much time I've put into implementing this stuff recently, I realized that there was more to say on this general subject, and I'm including it below.)
That said, I will go even further: these formats are designed for escaping e-mail addresses in the context of a larger standard and protocol, one that might already have special characters. This is why they contain so much quoting support.
This is then why the grammer is often so highly restricted for things that don't need to be quoted: given that an @ cannot be found in a domain name, you really shouldn't need to quote anything to the left of the @ to get a valid e-mail address.
However, "(" is a special character in a MIME field (begins a comment), and thereby if you want to include it in the local part of an e-mail address, you will need to escape it somehow; the same is true of things like whitespace, commas, or angle brackets.
The user typing the e-mail address into the form, however, isn't dealing with these restrictions: asking him to escape special characters in his e-mail address seems silly: one might as well be asking people to HTML escape their username in the username field.
That said, there is then a separate RFC 3696 which talks about the semantics of contemporary e-mail addresses and how one might go about validating them, and it includes the idea of quoting in its implementation (so maybe it believes that RFC 5321 is king).
Best comment ever. :) I feel that's something that's always missed in these discussions. Users are not entering RFC compliant email header values into your form. Maybe my next web app will make people base64 encode their name, and submit it in =?B?utf-8?..?= format.
Nowdays browsers should do the validation that provides immediate feedback to the users (using <input type=email ...>), so the article rightly claims that just sending an e-mail should be sufficient for the server side code. Most of the stuff that passes the browser's input filtering will be nonexistant rather than malformed addresses.
OTOH, most languages have proven, stable libraries for validating e-mail addresses (e.g. Mail::RFC822::Address for Perl).
The "send them a confirmation email" works well for registration, but there are legitimate use cases in which you don't want to do that.
When you just want to store the email address without acting on it (e.g., think a landing page for an app that hasn't been released), the best you can do is validate using a regex since sending them a confirmation email would provide no value to the user.
I can't stand when I try registering for a website with my email (which has ".com" in it... BEFORE the @ symbol) as invalid. I know it's a funky email to have, but it's valid and people often do these crazy checks.
I can see both sides though, on one hand you don't want someone accidently entering an invalid email and then never getting their email confirmation...
Article is spot on for all sorts of reasons. Never mind people typing in domain literals like me@[1.2.3.4].
Internationalised Domain Names are going to REALLY screw over some regexes, given how poorly understood Unicode is. Does Ruby even have Unicode regex support yet? I don't program in it so I'm unfamiliar with the state of the art.
On my pet topic of Unicode, I especially enjoy the use of hidden form fields to reverse-engineer the character encoding certain browsers ACTUALLY send on submission rather that what your code hoped for...
Good luck convincing management to Do The Right Thing here.
Due to a huge failure on my part, I edited the title to more accurately reflect my opinion on this. I did not mean to say that the regex validations themselves are a waste; my point was that the complex regular expressions are often too strict and almost always overkill.
This technique is hinted about, and I don't claim it as my own creation. I think the easiest (maybe not the best) route for both devs and users is:
[submit]
does email address have a '@' and a '.' after that?
yes -> send a validation email.
no -> Hey there, [email] seems like an odd address, are you sure?
yes -> send a validation email.
no -> restart
I think this does a reasonable job of staying out of everyone's way, and it catches a large percentage of the actual typographical/user error email entries.
Which MTAs do you suspect wouldn't deliver it? I've used internal zones of that form extensively without issue on all the common OSS MTAs (postfix, sendmail, exim).
I'm unaware of any common MTA software which wouldn't handle it.
The dk zone still has an A record (as one of the few?), so http://dk./ is a working web site name (though it redirects the the longer official Danish NIC).
imperialWicket's approach would still work fine in that case when john@dk clicks the "Yes, that's really my email adress" button - and I suspect he'd be pleasantly surprised to see it work, I'll bet he's got a very high expectation of that address failing completely on most websites...
I have a cow-orker who's first name is "G" - he's very used to poorly-validating websites claiming that his firstname is "wrong".
I've got another friend/acquaintance who's got a fully legal (self chosen) single name. No first/middle/last name, just a "mononym". He has the expected hilarious outcomes with things like Google's "real name policy".
This is precisely the reason why you let the user bypass your check with a confirmation. It's likely that most of your users who enter something without a period made a mistake. If someone is using an address like 'john@dk', I think they'd expect a message saying 'your email is invalid'; and seeing a message that just says, 'are you sure?' with a 'yes' option would be perfectly acceptable.
Edit: sorry for the echo, bigiain - I saw your post right after adding the comment.
One of the guys that managed the Norwegian (no.) USENET hierarchy and used to be responsible for newsgroup creation for it used to go under the nickname Dr. No. Whether because of the no prefix on the hierarchy, or because people liked to complain about it whenever he rejected a proposed group, I don't know. But people repeatedly suggested campaigns to get the .no NIC to let him have the address dr@no. Never got anywhere though.
The real problem is that lots of developers conflate validating that an email address "looks" correct with it actually being a valid, functioning address for that user.
There is no technical way to verify that an email address works other than sending it a message.
And if someone doesn't want to give you a real email address, they're just going to enter bogus@fake.com to get past the validation.
Using or not using a regex to validate email addresses misses the point. You should simply be delegating this task to the library that you’re using to send mail in the first place. If the mail library can’t deal with a particular address, then it’s not worth accepting because you’re not going to be able to send anything to it anyways.
If you have a Rails app you’re most likely using the Mail gem to send mail, so that’s why I wrote this: https://github.com/codyrobbins/active-model-email-validator. It lets the gem worry about whether an address is valid. Since the mail library is actively maintained, in my opinion it’s a safe bet to trust that it is properly parsing and validating addresses insofar as is possible.
153 comments
[ 3.1 ms ] story [ 228 ms ] threadA simple check for an "@" sign would go a long way to avoiding bounced mail notifications from usernames being entered in email address fields.
But not all the way. And so a simple "you might have got this wrong" flag would be helpful, no?
In our case, accounts may be created by third-party apps using REST JSON APIs, so we want to let the third-party app know that the email address isn't RFC-valid.
But yeah, that's effectively dead and you probably don't want to try sending mail that way.
Edit: punctuation.
Of course, whether any email server actually accepts that is a different story.
Anyway, the regexp I use is /.+@.+\..+/ which supports the address you describe, but (usually) catches the relatively common mistake of user@yahoo,com
We have seen a real email address without any dot, and it routes successfully to a TLD MX exactly like you describe so yes, it does happen. :)
There's very good odds that the email they send will have their "From:" (or "Reply-To:") address correctly set. Then just have an email autoresponder which emails them back a link with a token in it, when they click on that it'll take them to a page to create their account, with their email address already filled in by the token.
Ideally, all this would be done away with by OpenID or client-side certificates or something along those lines. The whole password-and-email-in-case-you-forget-it paradigm is broken, really.
So on our production servers, I need the @, but on our dev/text servers, I don't. And no, the domain is not appended to the address before sending. That's the part I actually know about.
http://stackoverflow.com/questions/201323/using-a-regular-ex...
and that demo email address may not be as valid as you think
http://isemail.info/%22Look%20at%20all%20these%20spaces%20%E...
No, you're excluding the set of emails that are entered incorrectly and thus are not valid. The result for those is not the same as if the UI included a simple test (such as your "ambitious" example).
1) Without UI validation:
- 1.1) Email address entered correctly -> activation email sent
- 1.2) Email address entered incorrectly but forms a valid address -> activation email sent to wrong address
- 1.3) Email address entered incorrectly but doesn't form a valid address -> activation email not sent
2) With UI validation:
- 2.1) Email address entered correctly -> activation email sent
- 2.2) Email address entered incorrectly but forms a valid address -> activation email sent to wrong address
- 2.3) Email address entered incorrectly but doesn't form a valid address -> user warned
-- 2.3.1) Email address re-entered correctly -> activation email sent
-- 2.3.2) other states
In the 1.3 case all of the activation emails fail to be sent. In the 2.3.1 case activation emails are sent that otherwise wouldn't be.
2.1a) Email address entered correctly -> validation fails, no mail sent
This prevents activation mails that would be sent without validation (or validation against a regex like [^@]+@[^@]+).
1: http://blog.nerdchic.net/archives/191/
Try http://news.ycombinator.com./ ;-)
However you still shouldn't be writing your own unless you're writing an email validation module of some kind. Laziness is a virtue after all.
I wish web forms had a "Tell us we are wrong" button next to validated boxes.
What the heck, how can I take MS Word online?
https://wikipedia.org/wiki/Postcodes_in_the_United_Kingdom#F...
Also, something not many people know is that any postcode in the UK has a maximum of 100 addresses in it.
You can tell I've been writing a search algorithm for UK address data recently ;)
Still, sending an email beats regex validation any day for determining it's a real, working address.
For example, I regularly receive email for an individual who has a nearly identical email address to my own, but at ymail.com instead of gmail.com. Any system that tries to guess at domain misspellings is going to catch ymail.com and think "Ah ha, they meant to type gmail.com, I'll correct that for them!" Viola, their email is sent to me. Again, this is not a theory, it happens to this poor guy all the time.
http://news.ycombinator.com/item?id=4486341
[1] https://github.com/Kicksend/mailcheck
Even worse than excessive validation is when they make you change your password often, for no apparent reason.
On some sites that do both (ahem Apple), the only way I can login if I haven't been there in awhile is the security questions or the password reset mechanism.
Weak password: correcthorsebatterystaplefoobarbaz
Strong password: password1
The worst is when they do that and enforce a maximum password of 8 or 12 characters (I'm looking at you, every bank in the US ever).
And I've have my problems with short addresses before with Microsoft. http://answers.microsoft.com/en-us/windowslive/forum/liveid-...
This is horrible practice from the perspective of a mail server. Too many illegitimate email addresses and you will start getting more "soft bounces" (a polite way to say, "We're not delivering this") when attempting to send mail. ISP's keep score for how accurate a mail server is when delivering mail, attempting to sift out spammers. When your score dips to a certain level, ISP's stop cooperating with you and basically label you as a "dubious/bad actor".
For a small-scale operation, perhaps this is okay. For anything larger or more vital, I wouldn't trust this method of operation, as it will at some point result in emails to legitimate addresses not being delivered. That's simply unacceptable for many applications.
Anyone who deals with forms of this nature will have seen this firsthand, and with enough frequency to cause trouble with mail relay as the person above has described. It's a real problem.
What's more common, someone accidentally typing "foo:ar@gmail.com" or "foonar@gmail.com"? Both would bounce and cause mails server issues.
If someone was being malicious, they can do it with an unregistered address that passes any validation you throw at it.
If there are legitimate emails that don't follow RFC, you should absolutely allow users to enter non-RFC-compliant email addresses.
I don't know that anyone uses it, or would even want to use it. It was a fun project, but I certainly wouldn't use it in an app (unless it was an MTA or MUA). What comprises a valid email address is way too broad.
I think there are reasonable regexes for email addresses FWIW. The RFC(s) are stupid and broken, and you can hit 99.99999% of addrs and provide useful errors back to the users with a regex.
http://github.com/sixarm/sixarm_ruby_email_address_validatio...
We use a combination of client-side JavaScript validation and server-side validation in Rails. Typical server-side validation is for REST JSON API calls by third-party apps, and also for parsing freeform text fields like "tell your friends about us".
Original code is by Tim Fletcher & Cal Henderson.
Don't test for an RFC-compliant address if you don't want to accept all RFC-compliant addresses. Being able to send an email is a much better test because it matches what you're going to use the email address for in your app.
It wouldn't be RFC-compliant, but it would catch 99% of typos.
Instead of being an error when the e-mail fails validation though, it would say something like: "your e-mail does not appear valid; please double check your entry. You will be sent an activation e-mail; click [Continue] if you're sure the address is valid."
Basically if it fails the "99%" test, then if that fails, let the user decide if their e-mail is in the 1% or not.
However, that specification, and the implementation you provide, is really designed for parsing e-mail address headers (as you say: for an MTA/MUA), and so contains a bunch of properties specific to structured MIME fields that really has nothing to do with e-mail addresses.
Instead, if you are verifying an e-mail address that someone types into a form, you probably are looking for "the kind of e-mail address that SMTP would accept for delivery", and that is covered by a different standard with a different and unrelated grammar.
Specifically, you implemented RFC 2822, the successor to RFC 822 that has now been obsoleted by RFC 5322, the standard on "Internet Message Format" (in essence, MIME). The related RFC 2821, the successor to RFC 821 that is now obsoleted by RFC 5321, is for SMTP.
For an example of the kinds of differences this would cause, RFC 5322 (with errata) believes that ""@example.com is invalid (by errata), but hello(ignore)@example.com is (MIME comment); RFC 5321, on the other hand, believes the exact opposite validity.
(edit: When I realized that I should probably write a blog post about this, given how much time I've put into implementing this stuff recently, I realized that there was more to say on this general subject, and I'm including it below.)
That said, I will go even further: these formats are designed for escaping e-mail addresses in the context of a larger standard and protocol, one that might already have special characters. This is why they contain so much quoting support.
This is then why the grammer is often so highly restricted for things that don't need to be quoted: given that an @ cannot be found in a domain name, you really shouldn't need to quote anything to the left of the @ to get a valid e-mail address.
However, "(" is a special character in a MIME field (begins a comment), and thereby if you want to include it in the local part of an e-mail address, you will need to escape it somehow; the same is true of things like whitespace, commas, or angle brackets.
The user typing the e-mail address into the form, however, isn't dealing with these restrictions: asking him to escape special characters in his e-mail address seems silly: one might as well be asking people to HTML escape their username in the username field.
That said, there is then a separate RFC 3696 which talks about the semantics of contemporary e-mail addresses and how one might go about validating them, and it includes the idea of quoting in its implementation (so maybe it believes that RFC 5321 is king).
OTOH, most languages have proven, stable libraries for validating e-mail addresses (e.g. Mail::RFC822::Address for Perl).
When you just want to store the email address without acting on it (e.g., think a landing page for an app that hasn't been released), the best you can do is validate using a regex since sending them a confirmation email would provide no value to the user.
I can see both sides though, on one hand you don't want someone accidently entering an invalid email and then never getting their email confirmation...
Internationalised Domain Names are going to REALLY screw over some regexes, given how poorly understood Unicode is. Does Ruby even have Unicode regex support yet? I don't program in it so I'm unfamiliar with the state of the art.
On my pet topic of Unicode, I especially enjoy the use of hidden form fields to reverse-engineer the character encoding certain browsers ACTUALLY send on submission rather that what your code hoped for...
Good luck convincing management to Do The Right Thing here.
[submit]
does email address have a '@' and a '.' after that?
yes -> send a validation email.
no -> Hey there, [email] seems like an odd address, are you sure?
I think this does a reasonable job of staying out of everyone's way, and it catches a large percentage of the actual typographical/user error email entries.[formatting edit]
I'm unaware of any common MTA software which wouldn't handle it.
I have a cow-orker who's first name is "G" - he's very used to poorly-validating websites claiming that his firstname is "wrong".
I've got another friend/acquaintance who's got a fully legal (self chosen) single name. No first/middle/last name, just a "mononym". He has the expected hilarious outcomes with things like Google's "real name policy".
Edit: sorry for the echo, bigiain - I saw your post right after adding the comment.
http://isemail.info/_system/is_email/test/?all
For example: !#$%&`*+/=?^`{|}~@iana.org is valid.
Here's an essay on the subject:
http://isemail.info/about
There is no technical way to verify that an email address works other than sending it a message.
And if someone doesn't want to give you a real email address, they're just going to enter bogus@fake.com to get past the validation.
http://fightingforalostcause.net/misc/2006/compare-email-reg...
If you have a Rails app you’re most likely using the Mail gem to send mail, so that’s why I wrote this: https://github.com/codyrobbins/active-model-email-validator. It lets the gem worry about whether an address is valid. Since the mail library is actively maintained, in my opinion it’s a safe bet to trust that it is properly parsing and validating addresses insofar as is possible.
one implementation is in lelp - http://www.acooke.org/lepl/rfc3696.html - but that package is no longer maintained (i know, because i wrote it).
i don't know of any other implementation. but that's the right way to do it. imho.