2012-01-19 49 views
3

我試圖創建一個Rails 3驗證,以確保人們不使用其中一個普通的免費電子郵件地址。Rails驗證NOT在正則表達式

我的想法是這樣的....

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." 

但無論是正常工作。有任何想法嗎?

回答

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」,「雅虎」 「的Hotmail」 - 在所有同時,這是不可能的。

你真正想要的是這樣的:

/ 
    [email protected]      # 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 = /[email protected](?!(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) 
+0

我看到你跟我的正則表達式說明了問題。但我已經嘗試過validates_format_of:email,:with => /[email protected](?!(gmail|yahoo|hotmail)\.).+$/i,但它似乎並沒有工作到目前爲止。 –

+0

我測試了你的正則表達式,它看起來應該起作用。我想我現在在我的rails驗證語法上有問題。 –

+0

我的驗證在某些情況下沒有觸發(如果我有一個孩子模型)。那只是一個不好的巧合。你的代碼是完美的。 –