AnApprentice
AnApprentice

Reputation: 110940

rails - REGEX for email validation

I'm looking for a regex to validate an email to learn if it's valid or not.. I have the following:

def is_a_valid_email?(email)
    email_regex = %r{
      ^ # Start of string
      [0-9a-z] # First character
      [0-9a-z.+]+ # Middle characters
      [0-9a-z] # Last character
      @ # Separating @ character
      [0-9a-z] # Domain name begin
      [0-9a-z.-]+ # Domain name middle
      [0-9a-z] # Domain name end
      $ # End of string
    }xi # Case insensitive

    (email =~ email_regex)
end

Problem with the above is [email protected] does not return as valid when it should be. Any thoughts or suggestions for a better regex?

Thanks

Upvotes: 19

Views: 67583

Answers (15)

jensgram
jensgram

Reputation: 31508

My shot at this (see comment and link above):

^.+@.+$

Upvotes: 12

Taufan Arif
Taufan Arif

Reputation: 460

correct format: [email protected]

rules:

  • no whitespace
  • character prefix + @ + domain + . + character suffix

simple answer:

def validate_email(email)
  (email =~ %r{^\S+@\S+\.\S+$}xi).present?
end

examples:

'email' # false (no '@' and no domain)
'email@' # false (no domain)
'email@domain' # false (domain format without '.')
'em ail@d omain.com' # false (whitespace included)
'@domain.com' # false (no character prefix)
'email@domain.' # false (no character suffix)
'[email protected]' # true

Upvotes: 4

Stanislav Kr.
Stanislav Kr.

Reputation: 554

URI module has a build-in regexp

URI::MailTo::EMAIL_REGEXP

Upvotes: 15

scragz
scragz

Reputation: 6690

validates_format_of :email, 
  :with => /^(|(([A-Za-z0-9]+_+)|([A-Za-z0-9]+\-+)|([A-Za-z0-9]+\.+)|([A-Za-z0-9]+\++))*[A-Za-z0-9]+@((\w+\-+)|(\w+\.))*\w{1,63}\.[a-zA-Z]{2,6})$/i

Don't ask me to explain it! That was from a validation plugin that I've since lost track of as all I needed was the email regex.

Upvotes: 25

Matt
Matt

Reputation: 47

Here's what we use.

We assume it's "something" @ "something" . "something" (2-4 characters). It should cover any "regular" email.

/^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/

Upvotes: -2

mindsupport
mindsupport

Reputation: 488

validates_format_of :email, :with => /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/i

Upvotes: -3

Swapnil Chincholkar
Swapnil Chincholkar

Reputation: 2909

For email validation, I come up with this regular expression,

/^[\w\d]+@[\w\d]+(\.[\w\d]+)+$/

Don't know how much it will help you but working fine for me.

If anyone find it failing for any email address please reply me so I will be able to work more on this.

Upvotes: 0

apanzerj
apanzerj

Reputation: 487

Not enough reputation to add a comment but if you are going to use the Devise regexp, and you are already using Devise itself, then you can simply use:

validates :email, presence: true, format: Devise.email_regexp

Upvotes: 21

Blair Anderson
Blair Anderson

Reputation: 20161

use: /\A[^@\s]+@[^@\s]+\z/

It asserts that there are no @ symbols or whitespaces in either the localpart or the domain, and that there is a single @ symbol separating the localpart and the domain.

More importantly: require email verification

As more tlds are being created, this is forward thinking.

This is from Devise , an industry standard for authentication.

Upvotes: 1

Buniowy
Buniowy

Reputation: 19

^.+@[\w]+\S[^\s]+$

A short improvement to first answer

Upvotes: 1

Epigene
Epigene

Reputation: 3908

In non-English locales you may need to verify emails with accented (unicode) characters such as čšēīū etc.

This method checks for a returned nil as a sign for a failed email validation in such locales:

def validate_unicode_email email
  /\A[\w\u00C0-\u017F\-]+(\.[\w\u00C0-\u017F\-]+)?@[\w\u00C0-\u017F\-]+\.[\w]{2,6}$/.match email
end

This will pass emails like [email protected], āpsis@mājās.lv, test_email@test_domain.org

Upvotes: -1

Sam Thornton
Sam Thornton

Reputation: 983

@jensgram's answer is really good, but it actually still allows for an email without a domain, e.g. foo@bar is as valid as [email protected].

Here's a slight variation on it that requires [email protected]:

/\A\S+@.+\.\S+\z/

or, more readable (though the parentheses aren't needed):

/\A(\S+)@(.+)\.(\S+)\z/

Play around with this

*Note: this regex is better than many, more complex ones, because of how incredibly diverse an email is allowed to be. Technically, an email can even use spaces if wrapped in quotes, e.g. "This is a valid email"@email.com

*Edit: I've replaced the ^ and $ with \A and \z to prevent a multiline anchor error in rails testing.

*Edit: Thanks to @Barry for noticing that the regex allowed white spaces. Updated the regex with \S to prevent emails with improper whitespaces. Multiple dots are still allowed as [email protected] is an acceptable address.

Upvotes: 14

user246672
user246672

Reputation:

Most of these other answers are too restrictive or allow addresses that are clearly wrong. So it's better to give up on being too strict, which will frustrate users and just get the main things right.

1. The most common use-case:

    validates :email, ..., format: { with: /\A[^@\s]+@([^@.\s]+\.)+[^@.\s]+\z/ }

2. To also allow root@localhost or homer@blinky, use this:

    validates :email, ..., format: { with: /\A[^@\s]+@([^@.\s]+\.)*[^@.\s]+\z/ }

None of the above replaces looking for CAPTCHAs, dns records, dns domain blacklists, IP blacklists and confirmation emails.

For real email domain validation, this can be used instead: https://gist.github.com/9200104

This horse is thoroughly beaten now, and being made into kibble.

Upvotes: 6

Mblake
Mblake

Reputation: 383

/\b[A-Z0-9._%a-z\-]+@(?:[A-Z0-9a-z\-]+\.)+[A-Za-z]{2,4}\z/

This is what I use to validate email.

Source: http://www.regular-expressions.info/email.html

Upvotes: 9

ryanprayogo
ryanprayogo

Reputation: 11817

Here's an email regex that I've been using for a while:

\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}\b

It's from here

Upvotes: 1

Related Questions