天天看點

第二篇詳細Python正規表達式操作指南(re使用)

接下來昨天的内容

執行比對

一旦你有了已經編譯了的正規表達式的對象,你要用它做什麼呢?`RegexObject` 執行個體有一些方法和屬性。這裡隻顯示了最重要的幾個,如果要看完整的清單請查閱 Python Library Reference

第二篇詳細Python正規表達式操作指南(re使用)
第二篇詳細Python正規表達式操作指南(re使用)

如果沒有比對到的話,match() 和 search() 将傳回 None。如果成功的話,就會傳回一個 `MatchObject` 執行個體,其中有這次比對的資訊:它是從哪裡開始和結束,它所比對的子串等等。

你可以用采用人機對話并用 re 子產品實驗的方式來學習它。如果你有 Tkinter 的話,你也許可以考慮參考一下 Tools/scripts/redemo.py,一個包含在 Python 發行版裡的示範程式。

首先,運作 Python 解釋器,導入 re 子產品并編譯一個 RE:

現在,你可以試着用

RE 的 [a-z]+ 去比對不同的字元串。一個空字元串将根本不能比對,因為 + 的意思是 “一個或更多的重複次數”。 在這種情況下

match() 将傳回 None,因為它使解釋器沒有輸出。你可以明确地列印出 match() 的結果來弄清這一點。

現在,讓我們試着用它來比對一個字元串,如 "tempo"。這時,match() 将傳回一個 MatchObject。是以你可以将結果儲存在變量裡以便後面使用。

現在你可以查詢 `MatchObject` 關于比對字元串的相關資訊了。MatchObject 執行個體也有幾個方法和屬性;最重要的那些如下所示:

試試這些方法不久就會清楚它們的作用了:

group()

傳回 RE 比對的子串。start() 和 end() 傳回比對開始和結束時的索引。span()

則用單個元組把開始和結束時的索引一起傳回。因為比對方法檢查到如果 RE 在字元串開始處開始比對,那麼 start() 将總是為零。然而,

`RegexObject` 執行個體的 search 方法掃描下面的字元串的話,在這種情況下,比對開始的位置就也許不是零了。

在實際程式中,最常見的作法是将 `MatchObject` 儲存在一個變量裡,然後檢查它是否為 None,通常如下所示:

findall() 在它傳回結果時不得不建立一個清單。在 Python 2.2中,也可以用 finditer() 方法。

子產品級函數

你不一定要産生一個

`RegexObject` 對象然後再調用它的方法;re 子產品也提供了頂級函數調用如 match()、search()、sub()

等等。這些函數使用 RE 字元串作為第一個參數,而後面的參數則與相應 `RegexObject` 的方法參數相同,傳回則要麼是 None

要麼就是一個 `MatchObject` 的執行個體。

Under the hood, 這些函數簡單地産生一個 RegexOject 并在其上調用相應的方法。它們也在緩存裡儲存編譯後的對象,是以在将來調用用到相同 RE 時就會更快。

你将使用這些子產品級函數,還是先得到一個

`RegexObject` 再調用它的方法呢?如何選擇依賴于怎樣用 RE 更有效率以及你個人編碼風格。如果一個 RE

在代碼中隻做用一次的話,那麼子產品級函數也許更友善。如果程式包含很多的正規表達式,或在多處複用同一個的話,那麼将全部定義放在一起,在一段代碼中提前編譯所有的

REs 更有用。從标準庫中看一個例子,這是從 xmllib.py 檔案中提取出來的:

我通常更喜歡使用編譯對象,甚至它隻用一次,but few people will be as much of a purist about this as I am。編譯标志

編譯标志讓你可以修改正規表達式的一些運作方式。在

re 子產品中标志可以使用兩個名字,一個是全名如 IGNORECASE,一個是縮寫,一字母形式如 I。(如果你熟悉 Perl

的模式修改,一字母形式使用同樣的字母;例如 re.VERBOSE的縮寫形式是 re.X。)多個标志可以通過按位 OR-ing 它們來指定。如

re.I | re.M 被設定成 I 和 M 标志:

這有個可用标志表,對每個标志後面都有詳細的說明。

IGNORECASE

使比對對大小寫不敏感;字元類和字元串比對字母時忽略大小寫。舉個例子,[A-Z]也可以比對小寫字母,Spam 可以比對 "Spam", "spam", 或 "spAM"。這個小寫字母并不考慮目前位置。

L

LOCALE

影響 "w, "W, "b, 和 "B,這取決于目前的本地化設定。

locales

是 C 語言庫中的一項功能,是用來為需要考慮不同語言的程式設計提供幫助的。舉個例子,如果你正在處理法文文本,你想用 "w+ 來比對文字,但 "w

隻比對字元類 [A-Za-z];它并不能比對 "é" 或 "ç"。如果你的系統配置适當且本地化設定為法語,那麼内部的 C 函數将告訴程式 "é"

也應該被認為是一個字母。當在編譯正規表達式時使用 LOCALE 标志會得到用這些 C 函數來處理 "w

後的編譯對象;這會更慢,但也會象你希望的那樣可以用 "w+ 來比對法文文本。

M

MULTILINE

(此時 ^ 和 $ 不會被解釋; 它們将在 4.1 節被介紹.)

使用 "^" 隻比對字元串的開始,而 $ 則隻比對字元串的結尾和直接在換行前(如果有的話)的字元串結尾。當本标志指定後, "^" 比對字元串的開始和字元串中每行的開始。同樣的, $ 元字元比對字元串結尾和字元串中每行的結尾(直接在每個換行之前)。

S

DOTALL

使 "." 特殊字元完全比對任何字元,包括換行;沒有這個标志, "." 比對除了換行外的任何字元。

X

VERBOSE

該标志通過給予你更靈活的格式以便你将正規表達式寫得更易于了解。當該标志被指定時,在

RE 字元串中的空白符被忽略,除非該空白符在字元類中或在反斜杠之後;這可以讓你更清晰地組織和縮進 RE。它也可以允許你将注釋寫入

RE,這些注釋會被引擎忽略;注釋用 "#"号 來辨別,不過該符号不能在字元串或反斜杠之後。

舉個例子,這裡有一個使用 re.VERBOSE 的 RE;看看讀它輕松了多少?

在上面的例子裡,Python 的字元串自動連接配接可以用來将 RE 分成更小的部分,但它比用 re.VERBOSE 标志時更難懂。

更多模式功能

到目前為止,我們隻展示了正規表達式的一部分功能。在本節,我們将展示一些新的元字元和如何使用組來檢索被比對的文本部分。

更多的元字元

還有一些我們還沒展示的元字元,其中的大部分将在下一章節展示。