Ruby Email validation with regex
I have a large list of emails I am running through. A lot of the emails have typos. I am trying to build a string that will check valid emails.
this is what I have for regex.
def is_a_valid_email?(email)
(email =~ /^(([A-Za-z0-9]*\.+*_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\+)|([A-Za-z0-9]+\+))*[A-Za-z0-9]+@{1}((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,4}$/i)
end
It passes if an email as underscores and only one period. I have a lot of emails that have more then one periods in the name itself. How do I check that in regex.
[email protected] # <~~ valid
foo.bar#gmail.co.uk # <~~~ not valid
[email protected] # <~~~valid
[email protected] # <~~ not valid
get_at_m.e@gmail #<~~ valid
Can someone help me rewrite my regex ?
This has been built into the standard library since at least 2.2.1
URI::MailTo::EMAIL_REGEXP
TL;DR:
credit goes to @joshuahunter (below, upvote his answer). Included here so that people see it.
URI::MailTo::EMAIL_REGEXP
Old TL;DR
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
Original answer
You seem to be complicating things a lot, I would simply use:
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
which is taken from michael hartl's rails book
since this doesn't meet your dot requirement it can simply be ammended like so:
VALID_EMAIL_REGEX = /\A([\w+\-]\.?)+@[a-z\d\-]+(\.[a-z]+)*\.[a-z]+\z/i
As mentioned by CAustin, there are many other solutions.
EDIT:
it was pointed out by @installero that the original fails for subdomains with hyphens in them, this version will work (not sure why the character class was missing digits and hyphens in the first place).
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-]+(\.[a-z\d\-]+)*\.[a-z]+\z/i
Here's a great article by David Celis explaining why every single regular expression you can find for validating email addresses is wrong, including the ones above posted by Mike.
From the article:
The local string (the part of the email address that comes before the @) can contain the following characters:
`! $ & * - = ` ^ | ~ # % ' + / ? _ { }`
But guess what? You can use pretty much any character you want if you escape it by surrounding it in quotes. For example, "Look at all these spaces!"@example.com is a valid email address. Nice.
If you need to do a basic check, the best regular expression is simply /@/
.
This one is more short and safe:
/\A[^@\s]+@[^@\s]+\z/
The regular is used in Devise gem. But it has some vulnerabilities for these values:
".....@a....",
"david.gilbertson@SOME+THING-ODD!!.com",
"a.b@example,com",
"a.b@example,co.de"
I prefer to use regexp from the ruby library URI::MailTo::EMAIL_REGEXP
There is a gem for email validations
Email Validator
Nowadays Ruby provides an email validation regexp in its standard library. You can find it in the URI::MailTo
module, it's URI::MailTo::EMAIL_REGEXP
.
In Ruby 2.4.1 it evaluates to
/\A[a-zA-Z0-9.!\#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/
But I'd just use the constant itself.