Rails验证不在正则表达式中

时间:2012-01-19 19:15:24

标签: ruby-on-rails ruby-on-rails-3

我正在尝试创建一个Rails 3验证,以确保人们不使用其中一个常见的免费电子邮件地址。

我的想法是这样的......

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

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

但两种方法都不正常。有什么想法吗?

1 个答案:

答案 0 :(得分:6)

基本上你写了一个匹配任何东西的正则表达式。让我们分解吧。

/
  ^(            # [ 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
/               # ]

当你想到它时,你会发现唯一不匹配的字符串是以“gmail”,“yahoo”,“hotmail”开头的字符串 - 所有在同时,这是不可能的。

你真正想要的是这样的:

/
  .+@                      # 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

把它放在一起,你有:

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

test_cases = %w[ foo@gmail.com
                 bar@yahoo.com
                 BAZ@HOTMAIL.COM
                 qux@example.com
                 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)