2011-04-30 113 views
1

的方法我想創建像這樣的方法:如何建立驗證電子郵件

def email_is_junk(email_address) 
end 

當它返回true,如果垃圾郵件,虛假如果郵件是不是垃圾...棘手的部分是我想要的邏輯是基於斷像以下條件:

[email protected]

  • 如果郵件在用戶A +,電子郵件是垃圾
  • 如果用戶包含3 NS字做,不回覆或支持,測試,服務技巧,微博提醒,調研,電子郵件是垃圾
  • 如果域名是craigslist.org,電子郵件是如何垃圾

建議寫這種方法不需要幾十個如果塊與正則表達式?

+0

無需編寫數十個數據塊..只需數十個正則表達式,然後您可以循環。或者爲了更好的(?)可維護性,編寫所有正則表達式和可能的字符串以在YAML /純文本文件中查找並加載(當然,如果您將要執行檢查*通常那麼最好避免加載文件的開銷 - 但基準測試並不會不必要地優化)。 – Zabba 2011-04-30 02:31:32

+0

謝謝,檢查將是非常有意義的。你能舉一個如何循環檢查的例子嗎?希望如果找到一場比賽,它可以打破效率? – AnApprentice 2011-04-30 02:43:02

回答

2

作爲一個例證以上Zabba的評論:

USER_RULES = ['\+', 'do-not-reply', 'support', 'test', 'service', 'tips', 'twitter', 'alerts', 'survey'] 
DOMAIN_RULES = ['craigslist.org'] 

def email_is_junk(email) 
    return true if !email.match('@') # return early if no @ 
    user, domain = email.split('@') 
    USER_RULES.each { |rule| return true if user.match(rule) } 
    DOMAIN_RULES.each { |rule| return true if domain.match(rule) } 
    false # reached the end without matching anything 
end 
+1

也許命名方法「junk_email_address?」還有什麼'email.split('0')'? – Zabba 2011-04-30 03:45:26

+0

謝謝,但不知道我遵循這裏發生的事情。回報不需要結束嗎? – AnApprentice 2011-04-30 05:33:28

+0

另外,這個錯誤與:動態常量賦值 USER_RULES = ['+','do-not-reply','suppor ... – AnApprentice 2011-04-30 05:35:46

0

這裏是一個JavaScript版本。不知道它可以比這更簡單:

function isJunk(email) { 
    return hasPlus(email) || supportLike(email) || craigsList(email); 
} 

function craigsList(email) { 
    return email.match(/@craigslist\.org/); 
} 

function supportLike(email) { 
    return email.match(/do-not-reply|support|test|service|tips|twitter|alerts|survey/); 
} 

function hasPlus(email) { 
    return email.match(/\+.*@/); 
} 

這只是一個啓發式,所以它不是100%準確。如果您仍有問題,請通過向用戶發送包含令牌的電子郵件來考慮驗證。

+0

「通過向用戶發送包含令牌的電子郵件來考慮驗證。」是肯定知道的唯一方式。電子郵件地址對於複雜的正則表達式來說太複雜了。 – 2011-04-30 04:39:40

1

看看Ruby的Regexp.unionRegexp.escape方法。它們可以很容易地基於文本或正則表達式字符串生成正則表達式模式。

這是從union文檔:

返回一個正則表達式對象,它是給定的圖案的結合,即,將匹配任何部件。這些模式可以是Regexp對象,在這種情況下,它們的選項將被保留,或者字符串。如果沒有給出模式,則返回/(?!)/。如果任何給定的模式包含捕獲,則行爲是未指定的。

Regexp.union       #=> /(?!)/ 
Regexp.union("penzance")    #=> /penzance/ 
Regexp.union("a+b*c")    #=> /a\+b\*c/ 
Regexp.union("skiing", "sledding") #=> /skiing|sledding/ 
Regexp.union(["skiing", "sledding"]) #=> /skiing|sledding/ 
Regexp.union(/dogs/, /cats/i)  #=> /(?-mix:dogs)|(?i-mx:cats)/ 

而且從escape文檔:

逃逸,將在正則表達式特殊含義的字符。返回一個新的轉義字符串,如果沒有字符轉義,則返回self。對於任何字符串,Regexp.new(Regexp.escape(str))=〜str將爲true。

Regexp.escape('\*?{}.') #=> \\\*\?\{\}\. 

這是一個起始點:

patterns = [ 
    /.+?\[email protected]/ 
] 

strings = [ 
    'do-not-reply', 'support', 'test', 'service', 'tips', 'twitter', 'alerts', 'survey', 
    'craigslist.org' 
] 

regex = Regexp.union(
    *patterns, 
    *strings.map{ |s| 
    Regexp.new(Regexp.escape("#{ s }@"), Regexp::IGNORECASE) } 
) 
pp regex 

>> /(?-mix:.+?\[email protected])|(?i-mx:do\-not\[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx:[email protected])|(?i-mx 

採用以上:

sample_email_addresses = %w[ 
    user 
    user+foo 
    do-not-reply 
    support 
    service 
    tips 
    twitter 
    alerts 
    survey 
].map{ |e| e << '@host.com' } 

pp sample_email_addresses.map{ |e| [e, !!e[regex]] } 

>> [["[email protected]", false], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true], 
>> ["[email protected]", true]] 

輸出示出了包含各測試地址的列表。 true意味着它們在正則表達式中觸發了一個命中,這意味着有什麼錯誤,並且false意味着它們是乾淨的並且被認爲是安全的。

如果你只是想失敗的那些,即匹配的正則表達式:

pp sample_email_addresses.select{ |e| e[regex] } 

>> ["[email protected]", 
>> "[email protected]", 
>> "[email protected]", 
>> "[email protected]", 
>> "[email protected]", 
>> "[email protected]", 
>> "[email protected]", 
>> "[email protected]"] 

如果你只想要通過的,也就是說,沒有在正則表達式觸發一擊:

pp sample_email_addresses.reject{ |e| e[regex] } 

>> ["[email protected]"] 
+0

謝謝,這是非常翔實的,但你如何採取這種做法返回真或假的方法?謝謝Tin Man – AnApprentice 2011-04-30 05:40:19

+0

我會添加一個例子。 – 2011-04-30 21:01:57