3

I'm trying to create a Rails 3 validation that will ensure that people are not using one of the common free email addresses.

My thought was something like this ....

validates_format_of :email, :with => /^((?!gmail).*)$|^((?!yahoo).*)$|^((?!hotmail).*)$/

or

validates_exclusion_of :email, :in => %w( gmail. GMAIL. hotmail. HOTMAIL. live. LIVE. aol. AOL. ), :message => "You must use your corporate email address."

But neither works properly. Any ideas?

1 Answer 1

6

Basically you've written a regex that matches anything. Let's break it down.

/
  ^(            # [ beginning of string
    (?!gmail)   #   followed by anything other than "gmail"
    .           #   followed by any one character
  )$            #   followed by the end the of string
  |             # ] OR [
  ^(            #   beginning of the string
    (?!yahoo)   #   followed by anything other than "yahoo"
    .           #   followed by any one character
  )$            #   followed by the end of the string
  |             # ] OR [
  ^(            #   beginning of the string
    (?!hotmail) #   followed by anything other than "hotmail"
    .*          #   followed by any or no characters 
  )$            #   followed by the end the of string
/               # ]

When you think about it you'll realize that the only strings that won't match are ones that start with "gmail," "yahoo," and "hotmail"--all at the same time, which is impossible.

What you really want is something like this:

/
  .+@                      # one or more characters followed by @
  (?!                      # followed by anything other than...
    (gmail|yahoo|hotmail)  # [ one of these strings
    \.                     #   followed by a literal dot
  )                        # ]
  .+                       # followed by one or more characters
  $                        # and the end of the string
/i                         # case insensitive

Put it together and you have:

expr = /.+@(?!(gmail|yahoo|hotmail)\.).+$/i

test_cases = %w[ [email protected]
                 [email protected]
                 [email protected]
                 [email protected]
                 quux
               ]

test_cases.map {|addr| expr =~ addr }
# => [nil, nil, nil, 0, nil]
#    (nil means no match, 0 means there was a match starting at character 0)
Sign up to request clarification or add additional context in comments.

3 Comments

I see the problem you explained with my regex. But I've tried validates_format_of :email, :with => /.+@(?!(gmail|yahoo|hotmail)\.).+$/i but it doesn't seem to work so far.
I tested your regex and it looks like it should work. I'm thinking I now have a problem with the syntax on my rails validation.
My validation wasn't firing in certain instances (if I had a child model). That was just a bad coincidence. Your code was perfect.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.