re --- 正規表示式 (regular expression) 操作¶
原始碼:Lib/re/
此模組提供類似於 Perl 中正規表示式的匹配操作。
被搜尋的模式 (pattern) 與字串可以是 Unicode 字串 (str),也可以是 8-bit 字串 (bytes)。然而,Unicode 字串和 8-bit 字串不能混用:也就是,你不能用 byte 模式匹配 Unicode 字串,反之亦然;同樣地,替換時,用來替換的字串必須與模式和搜尋字串是相同的型別 (type)。
正規表示式使用反斜線字元 ('\') 表示特別的形式,或是使用特殊字元而不觸發它們的特殊意義。這與 Python 在字串文本 (literal) 中,為了相同目的使用同一個字元的做法相衝突;舉例來說,為了匹配一個反斜線字面值,可能需要寫 '\\\\' 當作模式字串,因為正規表示式必須是 \\,而且每個反斜線在一個普通的 Python 字串文本中必須表示為 \\。另外,請注意在 Python 的字串文本中使用反斜線的任何無效跳脫序列目前會產生一個 SyntaxWarning,而在未來這會變成一個 SyntaxError。儘管它對正規表示式是一個有效的跳脫序列,這種行為也會發生。
解決方法是對正規表示式模式使用 Python 的原始字串符號;反斜線在一個以 'r' 為前綴的字串文本中不會被用任何特別的方式處理。所以 r"\n" 是一個兩個字元的字串,包含 '\' 和 'n',同時 "\n" 是一個單個字元的字串,包含一個換行符號。通常模式在 Python 程式中會使用這個原始字串符號表示。
請務必注意到大部分的正規表示式操作是可以在模組層級的函式和 compiled regular expressions 中的方法使用的。這些函式是個捷徑且讓你不需要先編譯一個正規表示式物件,但是會缺少一些微調參數。
也參考
第三方的 regex 模組,有著和標準函式庫 re 模組相容的 API,但是提供額外的功能以及更完整的 Unicode 支援。
正規表示式語法¶
一個正規表示式(或 RE)會指定一組匹配它的字串;這個模組的函式讓你可以檢查一個特定的字串是否匹配給定的正規表示式(或是給定的正規表示式是否匹配特定的字串,說到底是一樣的)。
正規表示式可以被連接 (concatenated) 成新的正規表示式;如果 A 和 B 都是正規表示式,則 AB 也是一個正規表示式。一般來說,如果一個字串 p 與 A 匹配,並且另一個字串 q 與 B 匹配,則字串 pq 會匹配 AB。或:這在以下情況下不成立:A*或 *B 包含低優先順序的運算子;或 A 和 B 之間的邊界條件 (boundary conditions);或是有編號群組 (numbered group) 的參照。因此,複雜的正規表示式可以輕鬆地從此處提到的簡單原始正規表示式建立。關於正規表示式的理論和實作,請參考 Friedl 書 [Frie09],或任何有關建構編譯器的書籍。
一個簡短的正規表示式格式解釋如下。如需更多資訊或以較平易的方式了解,請參閱 如何使用正規表示式。
正規表示式可以包含特殊和一般字元。大多數一般字元,如 'A'、'a' 或 '0' 是最簡單的正規表示式;它們只匹配它們自己。你可以連接一般字元,讓 last 匹配字串 'last'。(在本節的其餘部分,我們會用通常沒有引號的 這種特殊樣式 來書寫正規表示式,而被匹配的字串會 '在單引號中'。)
某些字元是特殊的,像 '|' 或 '('。特殊字元會代表一般字元的類別,或是會影響它們周圍正規表示式的解讀方法。
重複運算子或量詞 (quantifiers)(*, +, ?, {m,n} 等)不能直接嵌套使用。這樣避免了和非貪婪修飾符號後綴 ? 和其他實作中的修飾符號的模糊性。要在一個重複正規表示式內添加第二個重複,可以使用括號。例如:正規表示式 (?:a{6})* 會匹配任何六的倍數個 a 字元。
特殊字元包含:
.(點) 在預設模式下,這會匹配除換行符號外的任何字元。如果指定了
DOTALL旗標,這會匹配包含換行符號的任何字元。無論旗標為何,(?s:.)都會匹配任何字元。
^(插入符號) 會匹配字串的開頭,並且在
MULTILINE模式下,也會立即匹配緊接在每個換行符號之後的位置。
$匹配字串的結尾或是字串結尾的換行符號之前,並且在
MULTILINE模式下會匹配換行符號之前的位置。foo會匹配 'foo' 和 'foobar',而正規表示式foo$只會匹配 'foo'。更有趣的是,在'foo1\nfoo2\n'中搜尋foo.$,正常情況下會匹配 'foo2',但是在MULTILINE模式下會匹配 'foo1';在'foo\n'中搜尋單一個$會找到兩個(空的)匹配:一個在換行符號之前,一個在字串結尾。
*使得到的正規表示式匹配前面正規表示式的 0 或多次的重複,盡可能多次的重複。
ab*會匹配 'a'、'ab',或後面跟著任何數量個 'b' 的 'a'。
+使得到的正規表示式匹配前面正規表示式的 1 或多次的重複。
ab+會匹配後面跟著任何非零數量個 'b' 的 'a';它不會匹配 'a'。
?使得到的正規表示式匹配前面正規表示式的 0 或 1 次的重複。
ab?會匹配 'a' 或 'ab'。
*?,+?,??量詞 (quantifier)
'*'、'+'和'?'都是 greedy(貪婪的);它們會盡可能地匹配更多文字。有時候這種行為不是預期的;如果正規表示式<.*>被用來匹配'<a> b <c>',它會匹配整個字串,而不只是'<a>'。在量詞後添加?會讓他以 non-greedy(非貪婪的)或 minimal(最小的)方式進行匹配;盡可能匹配更少的字元。使用正規表示式<.*?>只會匹配到'<a>'。
*+,++,?+類似於量詞
'*'、'+'和'?',添加了'+'的量詞也會盡可能多次的匹配。然而,不同於真正的貪婪量詞,這些量詞在接續的正規表示式匹配失敗時不允許回溯 (back-tracking)。這些量詞被稱為 possessive (佔有的)量詞。例如,a*a會匹配'aaaa',因為a*會匹配全部 4 個'a',但是在遇到最後的'a'時,此正規表示式會回溯,以讓a*最終可以總共匹配 3 個'a',而第四個'a'會被最後的'a'匹配。然而,當a*+a被用來匹配'aaaa'時,a*+會匹配全部 4 個'a',但是當最終的'a'在尋找更多字元匹配失敗時,此正規表示式不能回溯並會因此匹配失敗。x*+、x++和x?+分別等同於(?>x*)、(?>x+)和(?>x?)。在 3.11 版被加入.
{m}指定應該恰好匹配 m 個前面的正規表示式;太少的匹配會造成整個正規表示式匹配失敗。例如,
a{6}會匹配恰好六個'a'字元,但不匹配五個。{m,n}使得到的正規表示式重複匹配前面的正規表示式 m 到 n 次,並嘗試盡可能多次的匹配。例如,
a{3,5}會匹配 3 到 5 個'a'字元。忽略 m 會指定下限為零,且忽略 n 會指定無限大的上限。舉例來說,a{4,}b會匹配'aaaab'或一千個'a'字元加上一個'b',但是不匹配'aaab'。不可以忽略逗號,否則量詞會與前述的形式混淆。{m,n}?使得到的正規表示式重複匹配前面的正規表示式 m 到 n 次,嘗試盡可能更少次的匹配。這是上一個量詞的非貪婪版本。例如,對六個字元的字串
'aaaaaa',a{3,5}會匹配 5 個'a'字元,而a{3,5}?只會匹配 3 個字元。{m,n}+使得到的正規表示式重複匹配前面的正規表示式 m 到 n 次,並嘗試盡可能更多次的匹配而不建立任何回溯點。這是上述量詞的佔有版本。例如,對六個字元的字串
'aaaaaa',a{3,5}+aa嘗試匹配 5 個'a'字元,然後需要再 2 個'a',會需要比可用的字元更多所以失敗,而a{3,5}aa會捕捉到 5 個'a',然後回溯成 4 個'a',接著最後兩個'a'會被模式中最後的aa匹配。x{m,n}+等同於