2010-07-10 27 views
53

我已經寫了一個函數用於向通訊庫添加電子郵件。在我添加檢查發送的電子郵件的有效性之前,它的工作完美無瑕。現在每次我收到「錯誤的電子郵件」。任何人都可以在這裏看到任何錯誤?所使用的正則表達式是:在django/python中檢查電子郵件的有效性

\b[\w\.-][email protected][\w\.-]+\.\w{2,4}\b,它是100%有效的(http://gskinner.com/RegExr/),但我可以使用它錯了,或者它可以是一些邏輯錯誤:

def newsletter_add(request): 
    if request.method == "POST": 
     try: 
      e = NewsletterEmails.objects.get(email = request.POST['email']) 
      message = _(u"Email is already added.") 
      type = "error" 
     except NewsletterEmails.DoesNotExist: 
      if validateEmail(request.POST['email']): 
       try: 
        e = NewsletterEmails(email = request.POST['email']) 
       except DoesNotExist: 
        pass 
       message = _(u"Email added.") 
       type = "success" 
       e.save() 
      else: 
       message = _(u"Wrong email") 
       type = "error" 

import re 

def validateEmail(email): 
    if len(email) > 6: 
     if re.match('\b[\w\.-][email protected][\w\.-]+\.\w{2,4}\b', email) != None: 
      return 1 
    return 0 
+4

100%有效嗎?不符合'foo + bar @ example.com',不會匹配'foo @ museum.com',而且更多。 – Kos 2013-12-23 10:37:26

+0

100%有效?你的正則表達式匹配'a .. @ .............. a'。 – Zenadix 2014-09-25 21:01:41

回答

131

更新2017:下面的代碼是7歲,並已修改,固定和擴大。對於希望現在做到這一點的人,正確的代碼,住在這裏:https://github.com/django/django/blob/master/django/core/validators.py#L168-L180

這裏是django.core.validators的一部分,您可能會發現有趣的:)

class EmailValidator(RegexValidator): 

    def __call__(self, value): 
     try: 
      super(EmailValidator, self).__call__(value) 
     except ValidationError, e: 
      # Trivial case failed. Try for possible IDN domain-part 
      if value and u'@' in value: 
       parts = value.split(u'@') 
       domain_part = parts[-1] 
       try: 
        parts[-1] = parts[-1].encode('idna') 
       except UnicodeError: 
        raise e 
       super(EmailValidator, self).__call__(u'@'.join(parts)) 
      else: 
       raise 

email_re = re.compile(
    r"(^[-!#$%&'*+/=?^_`{}|~0-9A-Z]+(\.[-!#$%&'*+/=?^_`{}|~0-9A-Z]+)*" # dot-atom 
    r'|^"([\001-\010\013\014\016-\037!#-\[\]-\177]|\\[\001-011\013\014\016-\177])*"' # quoted-string 
    r')@(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+[A-Z]{2,6}\.?$', re.IGNORECASE) # domain 
validate_email = EmailValidator(email_re, _(u'Enter a valid e-mail address.'), 'invalid') 

,所以如果你不這樣做想要使用表格和表格字段,您可以導入email_re並在您的功能中使用它,或者甚至更好 - 導入validate_email並使用它,捕捉可能的ValidationError

def validateEmail(email): 
    from django.core.validators import validate_email 
    from django.core.exceptions import ValidationError 
    try: 
     validate_email(email) 
     return True 
    except ValidationError: 
     return False 

,這裏是Perl中Mail::RFC822::Address regexp,如果你真的需要是偏執。

+0

謝謝,用email_re(這是整個網絡中的代碼片段)導入的,但你的第二個代碼塊做了竅門 – 2012-01-03 21:16:42

+2

這對於即將推出的新頂級域名擴展(超過6個字符的擴展名我認爲)是無效的http ://mashable.com/2011/06/21/icann-top-level-domains-change/ – jptsetung 2012-01-23 05:44:21

+0

我相信'email_re'表達式中可能存在一個錯誤。特別是在引用的字符串行中,我猜測的意圖是'\ 001-011'實際上應該是'\ 001- \ 011'。有什麼想法嗎? – kalefranz 2013-09-10 05:51:50

46

伊克,不,請,不要不要嘗試自己驗證電子郵件地址。這是人們從來沒有做的事情之一。

因爲您已經在使用Django,所以您最安全的選擇就是利用其電子郵件的表單驗證。按照文檔(http://docs.djangoproject.com/en/dev/ref/forms/fields/):

>>> from django import forms 
>>> f = forms.EmailField() 
>>> f.clean('[email protected]') 
u'[email protected]' 
>>> f.clean(u'[email protected]') 
u'[email protected]' 
>>> f.clean('invalid e-mail address') 
... 
ValidationError: [u'Enter a valid e-mail address.'] 
+9

[這是一個基於此方法的小型Python模塊](https://gist.github.com/3683902)。只需使用'isEmailAddressValid(address)'來執行驗證。 – 2012-09-09 11:35:15

+0

由於問題是關於Django的,所以這是最好的答案。爲了鼓勵代碼重用和簡單性+1。 – 2014-02-09 02:56:48

7

你理解錯了,但你不能做反正任務。有一種唯一的方法可以確定RFC 2822地址是否有效,即發送郵件並獲得響應。做其他任何事情都不會提高你的數據的信息內容,甚至是一點點。

當你給我validateEmail

[email protected] 

地址也擰人爲因素和接受屬性,你告訴我,我已經犯了一個錯誤,我告訴你的應用程序再見。

+0

幸運的是,這個正則表達式不是我的:)所以你也是正常的EmailField方法? – muntu 2010-07-10 03:48:08

+0

我不會說django,但該參數適用於語法驗證地址的任何嘗試。 http://code.djangoproject.com/ticket/3344看起來甚至沒有EmailField可能會達到任務(但我看起來並不真實) – msw 2010-07-10 04:02:13

+0

該特定票證自07/04/07以來被標記爲固定,並且在unicode處理翻譯的錯誤信息時出現錯誤。我認爲使用Django驗證器現在是相對安全的。 – cji 2010-07-10 07:08:38

0

從該變化開始您的代碼:

re.match( '\ B [\ W .-] + @ [\瓦特.-] + \ W {2,4} \灣',電子郵件)

這樣:

re.match(R'\ b [\ W .-] + @ [\瓦特.-] + \ W {2,4} \灣',email)

對我很好。

92
from django.core.exceptions import ValidationError 
from django.core.validators import validate_email 
try: 
    validate_email("[email protected]") 
except ValidationError as e: 
    print "oops! wrong email" 
else: 
    print "hooray! email is valid" 
+2

當問題最初被問到時,這個解決方案還沒有回來,但絕對是最好的答案。 – keithhackbarth 2015-01-29 19:51:48

+0

仍然是2017年的最佳答案..! 轉發至2018 ..!根據目前的流程,這應該是絕對可以接受的答案。 – Jay 2017-12-14 13:12:28

0

這個正則表達式將以合理的準確性驗證一個電子郵件地址。

\w[\w\.-]*@\w[\w\.-]+\.\w+ 

它允許字母數字字符,_.-

相關問題