Ruby Email validation with regex
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
Email validation in Ruby on Rails?
I use the constant built into URI in the standard ruby library
validates :email, format: { with: URI::MailTo::EMAIL_REGEXP }
What's the state of the art in email validation for Rails?
With Rails 3.0 you can use a email validation without regexp using the Mail gem.
Here is my implementation (packaged as a gem).
How can I validate multiple email addresses in a model?
You can use the TMail::Address module to validate an email as shown here. Custom validations can be added with the validate
method.
validate :check_email_addresses
def check_email_addresses
email_addresses.split(/,\s*/).each do |email|
TMail::Address.parse(email)
end
rescue TMail::SyntaxError
errors.add(:email_addresses, "are not valid")
end
Update: The TMail::Address module seems to be too lax on what is considered a valid email address (see comments below) so instead you can use a regular expression.
validate :check_email_addresses
def check_email_addresses
email_addresses.split(/,\s*/).each do |email|
unless email =~ /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\Z/i
errors.add(:email_addresses, "are invalid due to #{email}")
end
end
end
There are a variety of regular expression solutions for validating an email address. See this page for details.
rails - REGEX for email validation
My shot at this (see comment and link above):
^.+@.+$
How to validate email is real or fake in Rails?
you can use ruby gem to handle for checking email is real or fake. Awesome, it support validate for model.
https://github.com/minhquan4080/email_detected
What's the best way to validate multiple emails and handle errors in Rails?
Assuming this is a model that has_many emails, and the email model uses :validate_email, you could do something like the following:
class Foo < ActiveRecord::Base
validate :must_not_have_invalid_addresses
...
def emails=(addresses)
@invalid_addresses = []
addresses.split(",").each do |address|
@invalid_addresses.push(address) unless emails.create({:address => address})
end
end
def must_not_have_invalid_addresses
errors.add_to_base("Some email addresses were invalid") unless @invalid_addresses.empty?
end
end
This provides a validation error + an array of the invalid email addresses which you can make accessible to your view if you like.
rails email validation format and regex
Let us break down the expression (keep in mind the i
modifier makes it case insensitive):
\A (?# anchor to the beginning of the string)
[\w+\-.]+ (?# match 1+ a-z, A-Z, 0-9, +, _, -, or .)
@ (?# match literal @)
[a-z\d\-.]+ (?# match 1+ a-z, 0-9, -, or .)
\. (?# match literal .)
[a-z]+ (?# match 1+ a-z)
\z (?# anchor to the absolute end of the string)
This is what the tutorial defines as an email (in reality, it's much more complicated). So the author, Michael Hartl, wrote a couple tests for "valid" and "invalid" (according to the above definitions) emails.
Pretty much the "user" can be alphanumeric or contain _+-.
. The "domain" can be alphanumeric or -.
. And the "TLD" can only be letters. The first 5 emails use many variations of these previous rules as "acceptable" emails. The last 5 emails fail for the following reasons:
user@example,com
-,
can't be matcheduser_at_foo.org
- no@
user.name@example.
- no TLD after.
foo@bar_baz.com
- domain can't contain_
foo@bar+baz.com
- domain can't contain+
Obviously if you want more specific emails to match (or not match) add them to the array of tests. If your test fails, you know you will need to update your expression :)
Related Topics
Is There a Less Intrusive Alternative to Rspec's 'Should_Receive'
Ruby on Rails Error "Cannot Load Such File -- Less"
What Does the Fail Keyword Do in Ruby
Rails Erb Form Helper Options_For_Select :Selected
Dynamic Rails Routes Based on Database Models
Problem Signing Out with Devise on My App
How to Loop Over a Hash of Hashes
Homebrew Install: Failed During: Git Fetch Origin Master:Refs/Remotes/Origin/Master -N --Depth=1
How to Execute Ruby Template Files (Erb) Without a Web Server from Command Line
How to Check If a Variable Is a Number or a String
Ruby - Determining Method Origins
Rails3 Devise Undefined Method 'Confirmation_Url'