正規表示式

2021-07-15 22:33:40 字數 2915 閱讀 2006

之前一直對正規表示式有點陌生,人對陌生的東西,自然有點恐懼。最近正在學習爬蟲,看ryan mitchell的web scraping with python, 裡面有比較好的關於正規表示式的介紹,所以把它翻譯下來,分享給大家。

有一句計算機科學界的笑話「你有乙個問題,然後你決定用正規表示式去解決,好了,那麼你有兩個問題。」(看來大家對正規表示式的感受是一樣的)。

不幸的是,正規表示式(regex)通常是用有很多亂七八糟符號的**來教授的,看上去簡直和胡扯一樣,這容易令人生厭。然後當他們去工作的時候,本來可以用一行正規表示式搞定的東西,就會寫一大堆沒必要的搜尋和過濾函式。

你很幸運,看到這本書,因為正規表示式並沒有這麼難,而且確實很高效,而且用幾個例子就能很快的學會。

正規表示式之所以叫正規表示式(中文翻譯的總是這麼邪乎),就是因為它是用來識別有規律的字串(regular strings)。也就是說,給定正規表示式,對於文字來說,要麼「滿足規律,我返回」,要麼「不滿足規律,我不返回」。這在大文字中尋找比如像**號碼或者郵件位址這樣的字串的時候讓人感覺異常方便。

注意到我說regular strings,那麼什麼樣的字串算是有規律的字串?它是指任何可以通過一系列線性規則生成的字串,比如:

至少有乙個「a」

然後跟5個「b」

跟偶數個「c」

結尾可能以「d」結尾

滿足這些條件的字串有「aaaabbbbbccccd」,「aabbbbbcc」等等(總共有無限種變體)。

正規表示式其實就是這些規則的縮寫。比如,下面這個就是上面4個規則的正規表示式。

aa*bbbbb(cc)*(d | )

這個字串一看上去有點慌,但是當我們對它進行分解的時候,也就變得簡單了。

aa*

先寫乙個a,然後後面跟這a*,a*的意思是任意個數的a,包括0個從而保證至少有乙個a。

bbbbb

就是5個b。

(cc)*

任何偶數次的東西可以稱之為對,所以這裡要達到偶數次的c可以寫兩個c,然後用括號括起來,後面跟乙個星號,星號意味著可以有任何數量的c對,這裡同樣可以是0對。

(d | )

「|」這個的意思就是「或」,在這裡就是「d 」或「 」,這樣我們就可以保證最多乙個d結尾。

正規表示式的乙個經典的例子是識別乙個郵件位址。雖然對於不同的郵件伺服器來說,郵件位址的規則可能存在細微的不同,但我們還是可以發現一些通用的規則。對應的正規表示式出現在**的第二列。

規則正規表示式

[a-za-z0-9.+_]+:中括號的意思是可以是中括號中的任意乙個符號,加號的意思是這個符號或表示式可以出現任意次數,但至少要出現一次

規則2:有乙個「@」

@:在中間有且僅出現一次

規則3:必須跟至少乙個大寫或小寫字母

[a-za-z]+

規則4:必須有乙個英文句號

.

規則5:位址以org,com,edu,或者net結尾(現實中還有很多,這裡只舉例)

(org |com |edu |net)

連線所有的規則我們就得到乙個正規表示式:

[a-za-z0-9+_.]+@[a-za-z]+.(org |com |edu |net)

當要的寫乙個正規表示式的時候,最好先列乙個正規表示式的大綱,列出表示式所暗含的字串規則。注意特例,比如你是用來識別**號碼,你考慮了國家**了嗎?

最後,下表列出了常見的正規表示式符號,以及簡要的介紹和相應的例子。這個**絕對不完整,而且隨著語言的不同可能也有輕微的差別。無論如何這12個符號在python中最常用,他們可以用來查詢和收集大部分的字串。

符號意義

例子實際例子

*匹配前面的字元,子表示式,或者中括號字元,0次或多次

a*b*

aaaaa,bbbbb,aabb

+匹配前面的字元,子表示式,或者中括號字元,1次或多次

a+b+

aaab,abbb,aaaabbbb

匹配中括號中的任意字元

[a-z]*

()子表示式(這在正規表示式檢查順序中是第一位的)

(a*b)*

aaabab,aaab,abab

匹配前面的字元,子表示式,或者中括號字元m-n次(閉區間)

abaabbb,aaabbb,aabb

[^]不匹配中括號中任意乙個字元

[^a-z]*

|匹配任何乙個由「|」分隔開的字元,字串,或者子表示式

b(a|i|e)d

bad,bid,bed

.匹配任意單個字元(包括字元,數字或空格等)

b.dbad,bed,b d,b$d

^表明乙個字元或者子字串出現在整個字串的開頭^a\

轉義字元(它使得你可以使用特殊字元的字面形式)

\.\|\\

.|\$

放在正規表示式末尾,表示這裡是表示式的末尾。如果沒有這個符號,任意乙個表示式在末尾都相當於有乙個預設的「.*」

[a-z]*[a-z]*$

abcabc,zzzyx,bob

?!不包含。這個奇怪的字元對出現在乙個字元或者子表示式前面,表明這個字元或者子表示式不能出現在該字串中的該位置上。這用起來要小心,因為它並不排除該字元或者子表示式出現在字串的其它位置上。如果要在字串中完全消除某個字元或者子表示式,需要在兩端用^和$配合使用。

^((?![a -z]).)*$

no-caps-here, joewjjige

正規表示式 正規表示式 總結

非負整數 d 正整數 0 9 1 9 0 9 非正整數 d 0 負整數 0 9 1 9 0 9 整數 d 非負浮點數 d d 正浮點數 0 9 0 9 1 9 0 9 0 9 1 9 0 9 0 9 0 9 1 9 0 9 非正浮點數 d d 0 0 負浮點數 正浮點數正則式 英文本串 a za z...

正規表示式 表示式

網域名稱 a za z0 9 a za z0 9 a za z0 9 a za z0 9 interneturl a za z s 或 http w w w 手機號碼 13 0 9 14 5 7 15 0 1 2 3 5 6 7 8 9 18 0 1 2 3 5 6 7 8 9 d 號碼 x x x...

Linux正規表示式 編寫正規表示式

為了所有實用化的用途,你可以通過使用程式產生正確的結果。然而,並不意味著程式總是如你所願的那樣正確地工作。多數情況下,如果程式不能產生想要的輸出,可以斷定真正的問題 排除輸入或語法錯誤 在於如何描述想要的東西。換句話說,應該考慮糾正問題的地方是描述想要的結果的表示式。表示式不完整或者公式表示得不正確...