超詳細Python正規表示式操作指南(re使用),一
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正規表示式模式。Python 1.5之前版本則是通過 regex
模組提供 Emecs 風格的模式。Emacs 風格模式可讀性稍差些,而且功能也不強,因此編寫新程式碼時儘量不要再使用 regex
模組,當然偶爾你還是可能在老程式碼裡發現其蹤影。
就其本質而言,正規表示式(或
RE)是一種小型的、高度專業化的程式語言,(在Python中)它內嵌在Python中,並通過 re
模組實現。使用這個小型語言,你可以為想要匹配的相應字串集指定規則;該字串集可能包含英文語句、e-mail地址、TeX命令或任何你想搞定的東西。然後你可以問諸如“這個字串匹配該模式嗎?”或“在這個字串中是否有部分匹配該模式呢?”。你也可以使用
RE 以各種方式來修改或分割字串。
正規表示式模式被編譯成一系列的位元組碼,然後由用 C 編寫的匹配引擎執行。在高階用法中,也許還要仔細留意引擎是如何執行給定 RE ,如何以特定方式編寫 RE 以令生產的位元組碼執行速度更快。本文並不涉及優化,因為那要求你已充分掌握了匹配引擎的內部機制。
正規表示式語言相對小型和受限(功能有限),因此並非所有字串處理都能用正規表示式完成。當然也有些任務可以用正規表示式完成,不過最終表示式會變得異常複雜。碰到這些情形時,編寫
Python 程式碼進行處理可能反而更好;儘管 Python 程式碼比一個精巧的正規表示式要慢些,但它更易理解。
簡單模式
我們將從最簡單的正規表示式學習開始。python學習交流-719-139-688由於正規表示式常用於字串操作,那我們就從最常見的任務:字元匹配 下手。
有關正規表示式底層的電腦科學上的詳細解釋(確定性和非確定性有限自動機),你可以查閱編寫編譯器相關的任何教科書。
字元匹配
大多數字母和字元一般都會和自身匹配。例如,正規表示式 test 會和字串“test”完全匹配。(你也可以使用大小寫不敏感模式,它還能讓這個 RE 匹配“Test”或“TEST”;稍後會有更多解釋。)
這個規則當然會有例外;有些字元比較特殊,它們和自身並不匹配,而是會表明應和一些特殊的東西匹配,或者它們會影響到 RE 其它部分的重複次數。本文很大篇幅專門討論了各種元字元及其作用。
這裡有一個元字元的完整列表;其含義會在本指南餘下部分進行討論。
. ^ $ *+ ? { [ ] | ( )
我們首先考察的元字元是”[”
和
“]”。它們常用來指定一個字元類別,所謂字元類別就是你想匹配的一個字符集。字元可以單個列出,也可以用“-”號分隔的兩個給定字元來表示一個字元區間。例如,[abc]
將匹配”a”, “b”, 或 “c”中的任意一個字元;也可以用區間[a-c]來表示同一字符集,和前者效果一致。如果你只想匹配小寫字母,那么
RE 應寫成 [a-z].
元字元在類別裡並不起作用。例如,[akm$]將匹配字元”a”, “k”, “m”, 或 “$” 中的任意一個;”$”通常用作元字元,但在字元類別裡,其特性被除去,恢復成普通字元。
你可以用補集來匹配不在區間範圍內的字元。其做法是把”^”作為類別的首個字元;其它地方的”^”只會簡單匹配 “^”字元本身。例如,[^5] 將匹配除 “5” 之外的任意字元。
也許最重要的元字元是反斜槓”””。
做為 Python
中的字串字母,反斜槓後面可以加不同的字元以表示不同特殊意義。它也可以用於取消所有的元字元,這樣你就可以在模式中匹配它們了。舉個例子,如果你需要匹配字元
“[” 或 “””,你可以在它們之前用反斜槓來取消它們的特殊意義: “[ 或 “”。
一些用 “”” 開始的特殊字元所表示的預定義字符集通常是很有用的,象數字集,字母集,或其它非空字符集。下列是可用的預設特殊字元:
這樣特殊字元都可以包含在一個字元類中。如,[“s,.]字元類將匹配任何空白字元或”,”或”.”。
本節最後一個元字元是 . 。它匹配除了換行字元外的任何字元,在 alternate 模式(re.DOTALL)下它甚至可以匹配換行。”.” 通常被用於你想匹配“任何字元”的地方。
重複
正規表示式第一件能做的事是能夠匹配不定長的字符集,而這是其它能作用在字串上的方法所不能做到的。 不過,如果那是正規表示式唯一的附加功能的話,那麼它們也就不那麼優秀了。它們的另一個功能就是你可以指定正規表示式的一部分的重複次數。
我們討論的第一個重複功能的元字元是 *。* 並不匹配字母字元 “*”;相反,它指定前一個字元可以被匹配零次或更多次,而不是隻有一次。
舉個例子,ca*t
將匹配 “ct” (0 個 “a” 字元), “cat” (1 個 “a”), “caaat” (3 個 “a” 字元)等等。RE
引擎有各種來自 C 的整數型別大小的內部限制,以防止它匹配超過2億個 “a”
字元;你也許沒有足夠的記憶體去建造那麼大的字串,所以將不會累計到那個限制。
象 * 這樣地重複是“貪婪的”;當重複一個 RE 時,匹配引擎會試著重複儘可能多的次數。如果模式的後面部分沒有被匹配,匹配引擎將退回並再次嘗試更小的重複。
一步步的示例可以使它更加清晰。讓我們考慮表示式 a[bcd]*b。它匹配字母 “a”,零個或更多個來自類 [bcd]中的字母,最後以 “b” 結尾。現在想一想該 RE 對字串 “abcbd” 的匹配。
RE
的結尾部分現在可以到達了,它匹配 “abcb”。這證明了匹配引擎一開始會盡其所能進行匹配,如果沒有匹配然後就逐步退回並反覆嘗試 RE
剩下來的部分。直到它退回嘗試匹配 [bcd] 到零次為止,如果隨後還是失敗,那麼引擎就會認為該字串根本無法匹配 RE 。
另一個重複元字元是
+,表示匹配一或更多次。請注意 * 和 + 之間的不同;*匹配零或更多次,所以根本就可以不出現,而 +
則要求至少出現一次。用同一個例子,ca+t 就可以匹配 “cat” (1 個 “a”), “caaat” (3 個 “a”), 但不能匹配
“ct”。
還有更多的限定符。問號 ? 匹配一次或零次;你可以認為它用於標識某事物是可選的。例如:home-?brew 匹配 “homebrew” 或 “home-brew”。
最複雜的重複限定符是
{m,n},其中 m 和 n 是十進位制整數。該限定符的意思是至少有 m 個重複,至多到 n 個重複。舉個例子,a/{1,3}b 將匹配
“a/b”,”a//b” 和 “a///b”。它不能匹配 “ab” 因為沒有斜槓,也不能匹配 “a////b” ,因為有四個。
你可以忽略 m 或 n;因為會為缺失的值假設一個合理的值。忽略 m 會認為下邊界是 0,而忽略 n 的結果將是上邊界為無窮大 — 實際上是先前我們提到的 2 兆,但這也許同無窮大一樣。
細心的讀者也許注意到其他三個限定符都可以用這樣方式來表示。 {0,} 等同於 *,{1,} 等同於 +,而{0,1}則與 ? 相同。如果可以的話,最好使用 *,+,或?。很簡單因為它們更短也再容易懂。
使用正規表示式
現在我們已經看了一些簡單的正規表示式,那麼我們實際在 Python 中是如何使用它們的呢? re 模組提供了一個正規表示式引擎的介面,可以讓你將 REs 編譯成物件並用它們來進行匹配。
編譯正規表示式
正規表示式被編譯成 `RegexObject` 例項,可以為不同的操作提供方法,如模式匹配搜尋或字串替換。
re.compile() 也接受可選的標誌引數,常用來實現不同的特殊功能和語法變更。我們稍後將檢視所有可用的設定,但現在只舉一個例子:
RE
被做為一個字串傳送給 re.compile()。REs 被處理成字串是因為正規表示式不是 Python
語言的核心部分,也沒有為它建立特定的語法。(應用程式根本就不需要 REs,因此沒必要包含它們去使語言說明變得臃腫不堪。)而 re
模組則只是以一個 C 擴充套件模組的形式來被 Python 包含,就象 socket 或 zlib 模組一樣。
將 REs 作為字串以保證 Python 語言的簡潔,但這樣帶來的一個麻煩就是象下節標題所講的。
反斜槓的麻煩
在早期規定中,正規表示式用反斜槓字元 (“””) 來表示特殊格式或允許使用特殊字元而不呼叫它的特殊用法。這就與 Python 在字串中的那些起相同作用的相同字元產生了衝突。
讓我們舉例說明,你想寫一個 RE 以匹配字串 “”section”,可能是在一個 LATEX 檔案查詢。為了要在程式程式碼中判斷,首先要寫出想要匹配的字串。接下來你需要在所有反斜槓和元字元前加反斜槓來取消其特殊意義。
簡單地說,為了匹配一個反斜槓,不得不在 RE 字串中寫 “,因為正規表示式中必須是 “”,而每個反斜槓按 Python 字串字母表示的常規必須表示成 “”。在 REs 中反斜槓的這個重複特性會導致大量重複的反斜槓,而且所生成的字串也很難懂。
解決的辦法就是為正規表示式使用 Python 的 raw 字串表示;在字串前加個 “r” 反斜槓就不會被任何特殊方式處理,所以 r”
” 就是包含”” 和 “n” 的兩個字元,而 ”
” 則是一個字元,表示一個換行。正規表示式通常在 Python 程式碼中都是用這種 raw 字串表示。
相關文章
- python進階(20) 正規表示式的超詳細使用Python
- python 正規表示式re常用操作符 使用方法 怎麼用re正規表示式表示一個IP地址:0-255Python
- python正規表示式(re模組)Python
- python re模組 正規表示式Python
- Python 正規表示式 re 模組Python
- python中re模組的使用(正規表示式)Python
- Python 之 RE(正規表示式)常用Python
- python 關於正規表示式rePython
- python中的re(正規表示式)Python
- Python 正規表示式_re模組_使用compile加速PythonCompile
- Python模組學習: re 正規表示式Python
- Python爬蟲— 1.4 正規表示式:re庫Python爬蟲
- Python正規表示式簡記和re庫Python
- python爬蟲之re正規表示式庫Python爬蟲
- python基礎 之 正規表示式和re模組Python
- Python 正規表示式 re 模組簡明筆記Python筆記
- Python 正規表示式(RegEx)指南Python
- 詳解 Python 正規表示式Python
- Python正規表示式詳解Python
- 正規表示式及多語言操作指南
- python基礎操作——正規表示式Python
- 正規表示式詳細學習資料
- python就業班----正規表示式及re應用Python就業
- Linux正規表示式使用指南Linux
- JS正規表示式使用詳解JS
- 正規表示式使用詳解(轉)
- Python 正規表示式模組詳解Python
- Javascript正規表示式詳解(一)JavaScript
- Python 快速教程(標準庫01):正規表示式 (re包)Python
- Python正規表示式 findall函式詳解Python函式
- Python正規表示式常用函式詳解Python函式
- iOS正規表示式細說iOS
- 詳解正規表示式
- 正規表示式詳解
- re正規表示式庫的簡介、入門、使用方法
- 正規表示式re.compile的學習Compile
- Python爬蟲教程-19-資料提取-正規表示式(re)Python爬蟲
- LeetCode-10. 正規表示式匹配(Python-re包)LeetCodePython