4

I am currently using this code for my email validation:

/\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i

the problem is it still accepts emails with spaces like ab c@gmail.com.

I've tried a lot of variations of the code that should not allow spaces, but instead of refreshing the page with an error message at the top of the form, it gives me this error:

The provided regular expression is using multiline anchors (^ or $), which may present a security risk. Did you mean to use \A and \z, or forgot to add the :multiline => true option?

Martin Zabel
  • 3,589
  • 3
  • 19
  • 34
slwdi
  • 41
  • 1
  • 2
  • Missing anchors `^` and `$`. – Tushar Mar 16 '16 at 04:05
  • Try this ^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)* @[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$; – Piyush Gupta Mar 16 '16 at 04:10
  • Do you require your users to validate their email address? – dan-klasson Mar 16 '16 at 04:16
  • `'ab c@gmail.com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i => nil` - it's not the regex. Strange that you would be getting a warning recommending the use of \A\z when that's what you are using. Are you sure that warning is coming from the validation with that regex in it? It would be worth posting more of your model class. – Lucas Nelson Mar 16 '16 at 04:18
  • PS: you may want to borrow the regex from the Devise gem: `/\A[^@\s]+@([^@\s]+\.)+[^@\W]+\z/` so you don't have to worry about whether it's correct. – Lucas Nelson Mar 16 '16 at 04:25

5 Answers5

4

You are missing start and end anchor tag so you can refer this link Regular expressions with validations in RoR 4 and your correct regex will be,

/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i

You should try this regex also for email validation, this regex will fulfill your all requirement and checking all the required possible validation.

^[_A-Za-z0-9-\\+]+(\\.[_A-Za-z0-9-]+)*@[A-Za-z0-9-]+(\\.[A-Za-z0-9]+)*(\\.[A-Za-z]{2,})$

and Here is explanation of regex which will be useful for understanding validation

^           #start of the line
  [_A-Za-z0-9-\\+]+ #  must start with string in the bracket [ ], must contains one or more (+)
  (         #   start of group #1
    \\.[_A-Za-z0-9-]+   #     follow by a dot "." and string in the bracket [ ], must contains one or more (+)
  )*            #   end of group #1, this group is optional (*)
    @           #     must contains a "@" symbol
     [A-Za-z0-9-]+      #       follow by string in the bracket [ ], must contains one or more (+)
      (         #         start of group #2 - first level TLD checking
       \\.[A-Za-z0-9]+  #           follow by a dot "." and string in the bracket [ ], must contains one or more (+)
      )*        #         end of group #2, this group is optional (*)
      (         #         start of group #3 - second level TLD checking
       \\.[A-Za-z]{2,}  #           follow by a dot "." and string in the bracket [ ], with minimum length of 2
      )         #         end of group #3
$           #end of the line

Tested output:

Email is valid : abc@yahoo.com , true
Email is valid : abc-100@yahoo.com , true
Email is valid : abc.100@yahoo.com , true
Email is valid : abc111@abc.com , true
Email is valid : abc-100@abc.net , true
Email is valid : abc.100@abc.com.au , true
Email is valid : abc@1.com , true
Email is valid : abc@gmail.com.com , true
Email is valid : abc+100@gmail.com , true
Email is valid : abc-100@yahoo-test.com , true
Email is valid : abc , false
Email is valid : abc@.com.my , false
Email is valid : abc123@gmail.a , false
Email is valid : abc123@.com , false
Email is valid : abc123@.com.com , false
Email is valid : .abc@abc.com , false
Email is valid : abc()*@gmail.com , false
Email is valid : abc@%*.com , false
Email is valid : abc..2002@gmail.com , false
Email is valid : abc.@gmail.com , false
Email is valid : abc@abc@gmail.com , false
Email is valid : ab c@gmail.com , false
Email is valid : abc@gmail.com.1a , false
Community
  • 1
  • 1
Piyush Gupta
  • 2,181
  • 3
  • 13
  • 28
  • 1
    The regex in the question is not the problem, it already rejects 'ab c@gmail.com'. Changing the regex to something else will not fix the behaviour outlined in the question. Also, this regex will reject valid non-latin-alphabet domains and some valid gTLD domains. – Lucas Nelson Mar 16 '16 at 06:46
  • @LucasNelson, I checked that regex also there is only start and end anchor is missing so he can refer this link http://stackoverflow.com/questions/17759735/regular-expressions-with-validations-in-ror-4 and here i'm putting more cases of email validation. – Piyush Gupta Mar 16 '16 at 06:51
0

check this:

/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i
Ranzit
  • 1,327
  • 2
  • 13
  • 32
  • 1
    This does not answer the question as the regex listed in the question already rejects 'ab c@gmail.com'. It also is overly restrictive and will prohibit email addresses from non-latin-alphabet domains and some generic top-level domains. – Lucas Nelson Mar 16 '16 at 04:45
  • @Lucas I just checked it out. Its working fine with your input and other inputs as well. checked at rubular.com. Can you please recheck it – Ranzit Mar 16 '16 at 04:46
  • 1
    I'm not saying it's not a valid regex, I'm saying it won't help answer the original question (since both yours and the original question reject 'ab c@gmail.com'), and it can make matters worse by the assumption made about the domain part. See also http://stackoverflow.com/a/25982750. For example, `'webmaster@robsullivan.estate' =~ /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i => nil` … but that is a valid email address. – Lucas Nelson Mar 16 '16 at 04:56
0

Trying out your regular expression with different strings shows that it does_not accept something which looks like an email with spaces

'abc@google.com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => 0

'a abc@google.com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => nil

'abc a@google.com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => nil

'ab@goo gle.com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => nil

However there are a couple of problems with the regular expression. These strings should not be valid matches, but they are:

'a@google..com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => 0

'first..last@google..com' =~ /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  => 0

This regular expression avoids this problem: (please note that . needs to be escaped!)

 /\A([\w+\-]+\.)+[\w+\-]+@([a-z\d\-]+\.)+[a-z]+\z/i

But it is still not general enough.

You might want to check this question to improve the regexp:

What characters are allowed in an email address?

However, here is thought you might want to consider instead:

Don't validate the email with regexp, but rather validate implicitly by requiring the user to click on a link in a confirmation email you sent him/her

To implement a confirmation email, you can use Devise confirmable or build it manually: Rails - Add Email Confirmation to Registration System

A confirmation email is far easier and more straight-forward than trying to find the perfect regular expression for all email addresses in the world.

Shayan Shafiq
  • 1,447
  • 5
  • 18
  • 25
Tilo
  • 33,354
  • 5
  • 79
  • 106
0

You can use URI::MailTo::EMAIL_REGEXP

MaicolBen
  • 840
  • 1
  • 6
  • 20
0

Please try this regex once. I have tried that this regex solves the check of whitespaces, invalid "@" or "." characters (mostly duplicates).

^(?=.{0,64}@(\S))[A-Za-z0-9_-]+(\.[A-Za-z0-9_-]+)*[^-][A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*(\.[A-Za-z]{1,})(\S)$

I hope it solves the issue.

Hoping for improvement comments.

Shayan Shafiq
  • 1,447
  • 5
  • 18
  • 25