2010-08-30 75 views
2

我想知道如果這是一個好主意,避免正則表達式。避免正則表達式[python]

其實我避免它在任何情況下,有些人民一直給我意見,我不應該回避它,因爲如果你知道是什麼意思好像每一件事情:

[]「| 「 \ A \ B \ d \ D \ W \ w \ S \ Z $ *? ...

它會很容易閱讀,對嗎?但我倒像避免正則表達式我會有一個更可讀的代碼。

它變得更加無法讀取時,它的更大,例如:validators.py

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 

所以,我想知道一個理由,不能避免正則表達式?

+0

一封電子郵件。如果我的正則表達式閱讀技能仍然達到標準,那就很糟糕。 – muhmuhten 2010-08-30 02:00:44

+0

@sreservoir如在一個電子郵件地址? – NullUserException 2010-08-30 02:01:27

+6

我想避免編碼。我一直在避免它,但人們總是告訴我,我不應該避免它。但如你所知,這意味着使用大括號和怪異的資本化,這使得閱讀變得更加困難。 – 2010-08-30 02:01:45

回答

18

不,不要避免使用正則表達式。他們實際上是一個非常漂亮的小工具,如果你明智地使用它們,會爲你節省很多工作。

做什麼需要避免試圖使用它的一切,這似乎打擊那些新的正則表達式,他們變得有點鋼化玻璃和少一點迷戀:-)

之前萎靡不振例如,不要用它來驗證電子郵件地址。您驗證電子郵件地址的方式是通過鏈接發送電子郵件給收件人,該鏈接必須點擊以完成「交易」。

有數十億有效的電子郵件地址(根據RFC)沒有物理電子郵件接收器。 只有方式確定有一個接收器是發送一封電子郵件,並等待證據證實它已被接收並採取行動。

如果我發現自己編寫的正則表達式不止60個字符,我會回過頭來看看是否有更可讀的方式。同樣,如果我寫一個正則表達式並在一週後回來,並且無法立即識別它的作用,我想要替換它。這種特殊的段落是由我當然意見,但他們已經使我受益匪淺:-)

+4

我同意發送一封電子郵件來確認地址的存在是好的,但很高興檢查輸入的電子郵件地址是否無效。用戶可能會忘記'@',你可以檢查它是否在那裏並給出錯誤。做到這一點比接受它更好,並通過電子郵件發送失敗。用戶不知道他爲什麼沒有收到他的電子郵件。 – avacariu 2010-08-30 02:34:24

+4

@ vlad003 - 那麼你只需使用'if'@「in email_address ...' - 在這種情況下,正則表達式是過度殺傷。任何比這更復雜的事情,你要求麻煩... – detly 2010-08-30 03:30:08

+0

@vlad,檢查一個「@」和你必須使用一個完全驗證的電子郵件地址的怪物之間有很大的區別。通過一切手段做一個這樣的簡單檢查,它至少是可讀的:-) – paxdiablo 2010-08-30 03:32:33

2

如果您選擇使用一個更一般的分析方法,像pyparsingPLY,你將永遠不會需要正則表達式(其只能匹配與這些一般解析器匹配的語言的一小部分)。然而,諸如PLY這樣的詞法分析器通常是圍繞正則表達式構建的(這與詞法分析器的需求完美匹配!),因此您可能必須避免這種情況(以及功能強大的工具,例如BeautifulSoup,當任何「正常」用戶只需傳遞一個正則表達式對象作爲選擇器就可以繼續使用和享受它,因爲BeautifulSoup完全支持這一點),並且必須用您選擇的通用解析包重新編碼許多這樣的現有解析器。

當然,如果更簡單,高度優化和簡潔的應用程序是一個完美的解決方案,那麼性能可能會受到很大的影響,而且代碼的大小可能會「爆炸」,變得非常大很多常見的情況。但是,如果你不介意讓程序兩倍大,兩倍慢,並決心不惜一切代價避免正則表達式,你可以可以做到這一點。另一方面,如果你主要關心的是可讀性(也是一個可以理解和值得關注的問題),那麼re.VERBOSE選項通過在RE模式中充分使用空格和註釋,可以真正實現奇蹟該目標沒有刪除RE的優勢(除了稀釋一個有時過分的簡潔;-))的任何。你會想保持至少一個通用分析系統,在你的腰帶,當然(而不是拉伸的RE做他們是錯的任務,所以很多人不幸呢!) - 但最小的命令的REs會在很多情況下爲您提供良好的服務(包括例如充分利用BeautifulSoup以及其他許多可以接受RE作爲參數的工具),我認爲這是相當值得推薦的。

6

正則表達式是一種工具。它們完全適合於某些任務,而不適用於其他任務。像任何工具一樣,在他們是工作的正確工具時使用它們。不要只因爲有人說他們不好就避免他們。學習如何使用它們,然後你可以自己決定,而不是依賴別人的教條。

-1

正則表達式是可能用於提取/驗證電子郵件地址正確的工具...

從原始文本中提取一個或多個電子郵件地址:

import re 
pat_e = re.compile(r'(?P<email>[\w.+-][email protected](?:[\w-]+\.)+[a-zA-Z]{2,})') 
emails = [] 
for r in pat_e.finditer(text): 
    emails.append(r.group('email')) 
return emails 

要查看是否有單件的文本是一個有效的電子郵件:

import re 
pat_m = re.compile(r'([\w.+-][email protected](?:[\w-]+\.)+[a-zA-Z]{2,}$)') 
if pat_m.match(text): 
    return True 
return False 
+1

對於某個電子郵件地址的'@',它是[完全有效](http://en.wikipedia.org/wiki/Email_address#Specification)之前的加號('+'),這會失敗。 – detly 2010-08-30 03:35:57

+2

當他們決定創建一個5個字母的TLD時會發生什麼? – Gabe 2010-08-30 03:54:59

+1

曾聽說過.museum和.travel頂級域名? – Schnouki 2010-08-30 11:52:08

1

只是一些comparisions,在這裏我的版本的電子郵件格式檢查不與正則表達式(測試用例)和一個可讀的正則表達式提供給我作爲替代(雖然它被接受後,發送電子郵件,是偉大的想法):

# -*- coding: utf8 -*- 
import string 
print("Valid letters in this computer are: "+string.letters) 
import re 
def validateEmail(a): 
    sep=[x for x in a if not (x.isalpha() or 
           x.isdigit() or 
           x in r"!#$%&'*+-/=?^_`{|}~]") ] 
    sepjoined=''.join(sep) 
    ## sep joined must be [email protected] form 
    if len(a)>255 or sepjoined.strip('.') != '@': return False 
    end=a 
    for i in sep: 
     part,i,end=end.partition(i) 
     if len(part)<2: return False 
    return len(end)>1 

def emailval(address): 
    pattern = "[\.\w]{2,}[@]\w+[.]\w+" 
    return re.match(pattern, address) 

if __name__ == '__main__': 
    emails = [ "[email protected]","[email protected]", "[email protected]", 
       "[email protected]", "[email protected]","marjaliisa.hämälä[email protected]", 
       "marja-liisa.hämälä[email protected]", "[email protected]",'[email protected]', 
       '[email protected]','[email protected]'] 

    print('\n\t'.join(["Valid emails are:"] + 
         filter(validateEmail,emails))) 

    print('\n\t'.join(["Regexp gives wrong answer:"] + 
         filter(emailval,emails))) 

""" Output: 
Valid letters in this computer are: abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ 
Valid emails are: 
     [email protected] 
     [email protected] 
     [email protected] 
     [email protected] 
     [email protected] 
Regexp gives wrong answer: 
     [email protected] 
     [email protected] 
     [email protected] 
""" 

編輯:從這個古老的代碼清理正則表達式過濾功能,編輯的@detly基於鏈路更加寬容的版本。在發送確認電子郵件之前,我已經足夠填寫表格了。 Finaly在評論中提到了255字符長度限制檢查。

此代碼按用途不接受正常的一個@ B中有效的電子郵件地址,但不會接受我@地方。另一件事是它取決於isalpha返回。所以這個來自Ideone.com的輸出結果並不接受斯堪的納維亞öä,即使它們現在也是有效的。在我的家用電腦上運行時,這些被接受。即使編碼線在那裏。

0

(刪除的正則表達式,自稱是一個「官」之一,但其實是在它聲稱是從RFC沒有找到。)

This正則表達式可能是有趣的,因爲它是試圖精確匹配舊版互聯網郵件標準中提供的電子郵件地址語法。

+0

把「官方」放在引號內是一個死的東西,它是什麼,但官方:-) – paxdiablo 2010-08-30 05:14:16

+0

我去尋找「官方」是如何,發現你是對的。因此,我將一個鏈接換成了一個更加流暢的正則表達式,聲稱它能夠滿足大部分RFC 822標準。 :-) – kindall 2010-08-30 05:48:47

0

不用多說正則表達式是一個非常強大的工具,如果你有興趣做網頁抓取或基本上是包括大量的文字處理模式的任何其他任務,你必須學習正則表達式。

現在,閱讀文檔,是不是很有趣,所以我建議你使用this chrome plugin練習您正則表達式的技能。這是一種非常有趣的方式來測試一個正則表達式是否符合您的要求,並且可以幫助您更快地學習語言。

好練習:)