1. 程式人生 > >正則表示式語法速查

正則表示式語法速查

正則表示式(RE)模組的功能主要是設定一個字串並搜尋其中的字串;這個模組的功能讓你檢查一個特定的字串,匹配給定的正則表示式(或正則表示式匹配特定的字串,它可以歸結為對同樣的事情,一般情況下,NFA引擎是由表示式主導,而python的re正是NFA引擎,從引擎的機制上來描述,應該是理解為拿正則表示式匹配特定的字串;DNF引擎反之,詳細可參考精通正則表示式一書關於正則引擎的章節)。

正則表示式可以被連線在一起,形成新的正則表示式,如果A和B都是正則表示式,那麼AB同時也是正則表示式。一般來說,如果一個串p匹配了A,另外一個串q匹配了B,那麼串pq會匹配AB。這種情況不包含A或B使用了低優先順序描述(非貪婪匹配模式),命名捕獲組(反向引用)。因此,複雜的表示式可以很容易地從簡單易建的子表示式來描述的。對於理論和正則表示式的執行細節,請參考本書的引用,或幾乎任何編譯器構造的文件。
這裡包含關於正則表示式的進一步資訊和詳細報告、使用指南:http://www.python.org/doc/howto/
正則表示式可以同時包含元字元(直譯為特殊字元,國內一般稱為元字元)和普通字元。大多數普通字元,如“a”,“1”或“0”,是最簡單的正則表示式,它們只是描述本身。您可以連線普通的字元,因此last匹配字串'last'。 (在本節的其餘部分,我們將按照這種格式來描述,表示式通常不帶引號,和包含在單引號的字串進行匹配。)
一些字元,如“|”或“(”,是特殊的字元。特殊符號會對普通字元進行分組或者影響臨近的普通字元、表示式。

包括以下元字元:
.
(Dot)在預設模式下,它匹配除了換行符號以外的任意字元。如果指定了DOTALL,那它將可匹配換行符。要顯式匹配一個句點符號本身,要用反斜線轉義,例如, "\."



^
(Caret)匹配字串的開始,即物理行的開始,在多行模式下,也可匹配換行符後的位置,即邏輯行的開始。  \A也可以,用於沒有^字元的鍵盤 



$
匹配字串的結尾或在字串尾部的換行符之前的位置,在多行模式下,還可以匹配到一個新的行之前的位置。foo可以匹配'foo'和 'foobar',而foo$只匹配'foo'。更有趣的是,在'foo1\nfoo2\n'中搜索foo.$,預設模式下匹配到'foo2',而在多行 模式下,可匹配到'foo1'和'foo2'。 \Z也可以,用於沒有$字元的鍵盤不指定多行模式,字元的鍵盤  不指定多行模式,$匹配物理行的結尾,而foo1為串的邏輯行之前的字元,所以未被匹配。 



*

描述前邊鄰近的字元或子表示式,匹配0個或多個重複,因為許多重複是有可能的。ab*將匹配'a','ab',或者'a'後面跟大量的'b'。 



+
描述前邊鄰近的字元或子表示式,匹配1個或多個重複。ab+將匹配'a'和後面跟著不少於1個的b,但不單獨匹配'a'。  



?
描述前邊鄰近的字元或子表示式,匹配0個或1個重複。ab?將匹配'a'或'ab'。



*?、+?、??
使用"*"、"+"、"?" 這些量詞描述符都是貪婪匹配的,它們會匹配儘可能多的字元。有時,這種行為並非是我們想要的,若使用<.*>去匹配 '<H1>title</H1>',它將會匹配整個字串,而不只是'<H1>'。在量詞描述符後面新增"?"後, 會使匹配過程裡,變為非貪婪模式,匹配儘可能少的字元。使用<.*?>去匹配之前的字串,將只匹配<H1>。



{m}
描述前邊鄰近的字元或子表示式,嘗試匹配儘可能多的m個重複。例如,a{6}匹配6個'a',不是5個。



{m,n}
描述前邊鄰近的字元或子表示式,嘗試匹配儘可能多從m個到n個重複。例如a{3,5}將匹配3至5個'a'
省略m,預設為0,即是匹配下限為 0個,
省略n,則是匹配上限為無限。
例如,a{4,}將匹配'aaaab'裡的4個a或其中包含成千上萬個'a',但最少應該有4個'a',並不匹配 'aaab',逗號不可省略,以免與之前介紹的描述符衝突。



{m,n}?
描述前邊鄰近的字元或子表示式,嘗試匹配儘可能少從m個到n個重複。這是非貪婪版本的{m,n}。例如,在6個字元的字串'aaaaaa',a{3,5}將匹配5個'a',而a{3,5}?將匹配3個'a'。



\\
用於轉義元字元,或者簡寫標記的宣告(將在下邊談論)。如果在python裡你不適用raw原始字串來作為表示式,請記住,表示式還需要為每 個反斜杆前邊在用一個反斜杆來轉義。若轉義序列並非由python作解析,那麼\將會直接修飾之後的字元。但是如果由python來解釋表示式,反斜杆應 該重複2次。這比較複雜,不容易理解,所以強烈建議使用最簡單的raw格式的原始字串來寫表示式。例如,r"aaa\(a\)"匹配'aaa(a)', 假如使用普通字串來編寫表示式:"aaa\\(a\\)"。

[][]



[]

[]內任選一個,用於描述一個字元組(臺翻譯為字符集)。字元組可以是由多個單獨字元組成,也可以使用連字元-來表示字元範圍。特殊字元在字元組裡是無效的,只作為普通字元描述。例如,[akm$]是匹配'a'、'k'、'm'、'$'裡的其中一個字元;[a-z]將匹配所有小寫字母,[a- zA-Z0-9]將匹配所有字母和數字;簡寫標記也可以在字元組裡描述。如果你想包含']'或者'-',那就在該字元前使用反斜杆轉義,或者將它寫在字元 組的第一個,例如[]]匹配']',注意,假如同時需要匹配'-'和']',就只能把其中一個放在第一位,另一個用反斜杆轉義,推薦對所有不需要的元字元都使用反斜杆轉義。您還可以匹配一個除了字元組裡描述字元以外的字元,以脫字元'^'作為第一個字元,將標示這是一個排除型字元組,^在別的位置,只會匹配普通的'^'字元。
例如,[^]匹配任意一個不在中括號裡的字元;[^^]匹配除了脫字元以外的字元。

|
A|B,其中A和B可以是任意的子表示式,該表示式將可匹配A或者B。表示式裡可以使用任意數量的|進行多選分支的分隔。這可用於分組捕獲等 (見下文)。對目標字串進行掃描時,|是從左到右的順序進行分隔。當一個分支被完全匹配,那麼該分支就會被接受,這以為著,一旦A匹配,B就永遠不會被 嘗試匹配。即使B會匹配更長的字串。換句話說,在|操作符裡,是永遠不會貪婪匹配的。要匹配一個普通字元|,可使用\|轉義寫法,或者用字元組包含: [|]。

(...)
正則表示式會匹配括號內的字元,從開始字元到結束字元分為一個組,該組在捕獲完成之後,可使用\數字來進行反向引用。需要匹配字元'('、')'時,使用轉義符進行轉義'\('、'\)',或者用字元組:[(]、[)]。從Group 1開始

(?...)
捕獲組中可使用擴充套件功能符,在(之後使用?,在?之後描述進一步的語法含義。擴充套件通常不會進行新的捕獲,(?P<name>)除外。
以下是目前支援的擴充套件功能:

(?iLmsux)
(可以一個或者多個修飾符同時使用:'i','L','m','s','u','x')
該組匹配空字串;在模組中,相應的設定標誌:re.I/IGNORECASE,re.L,re.M,re.S/DOTALL,re.U,re.X/VERBOSE。如果你需要在表示式中指定匹配標 志,而不是通過編譯函式來指定,這是非常有用的,編譯標誌將影響整個表示式。請注意,(?x)的標誌改變表示式的書寫規則,如果在該標誌之後包含了空白字 符,那空白字元將會被忽略。例如aa(?i)a可匹配'AaA'。

(?:)
捕獲組的無捕獲版本。正則表示式會捕獲任何在括號內的內容,但該捕獲組不會捕獲任何內容,也不可用於反向引用。一般用於做子表示式的界定符,例如給aa|b加限定:a(?:a|b)匹配'a'之後還有'a'或者'b',而不是原本的匹配'aa'或者匹配b。

(?P<name>...)
功能類似捕獲組,但該組匹配後可通過一個名稱來引用捕獲內容。分組名必須是有效的python識別符號,每個組名在一個表示式只能被用一次。一個 沒有宣告組名的捕獲組其實也是一個id編號組。所以在上面的例子裡,也可以把組命名並且進行反向引用。例如,表示式是:(?P<id>[a- zA-Z_]\w*),該匹配結果的物件可通過指定組名來返回,m.group('id')或者m.end('id'),並且在表示式中可用 (?P=id)來進行反向引用,或者用\g<id>進行替換文字。
示例:

```python
>>>m = re.match('a(?P<id>b)cde','abcde') #命名捕獲組id捕獲b
>>>m.group() #獲取所有成功匹配內容
'abcde'
>>>m.group('id') #獲取id組捕獲內容
'b'
>>>m.end('id') #獲取id組成功匹配結束位置點
2
>>>m.end() #獲取整個表示式成功匹配結束位置點
5
>>>m = re.match('a(?P<id>b)cde(?P=id)','abcdeb') #反向引用了id組
>>>m.group()
'abcdeb'
>>>re.sub('a(?P<id>b)cde(?P=id)','ab\g<id>h','abcdeb') 在替換中指定替換為id組的內容(b)
'abbh'
```

(?P=name)
反向引用,匹配之前對應的命名組所捕獲的內容。

(?#...)
註釋,包含在該括號內的內容將被忽略。

(?=...)
如果當前位置可匹配...,那麼匹配接下來的表示式,但這個匹配只是一個判斷,它並不消耗、佔有任何字元,這被稱為後向斷言(順序肯定環視)。例如Isaac (?=Asimov)可以匹配Isaac,但它後邊必須跟著'Asimov'。

(?!...)
如果當前位置不可匹配...,那麼匹配接下來的表示式。這是後向否定斷言(順序否定環視),例如,Isaac (?!Asimov) 會匹配 'Isaac ' ,當它後邊不是跟著 'Asimov'的時候。

(?<=...)
如果當前位置點的前面符合某些條件,那麼從這個點開始匹配接下來的表示式。這被稱為前向斷言(逆序肯定環視)。 (?<=abc)會找到一個匹配在字串'abcdef'中,在匹配位置點向前檢查三個字元,符合包含在斷言裡的描述的三個字元。斷言所包含的表達 式必須是固定長度的(不能使用量詞修飾),這意味著a|b是被允許的,而a*、a{3,4}是不允許的。請注意,使用後向斷言永遠不會從字串開始進行匹 配,你需要使用的函式可能是search(),而不是match(),因為match()是從字串開頭進行匹配,否則失敗,而使用環視功能會導致該函式失敗:

(?<!...)
如果當前位置點的前面不符合某些條件,那麼從這個點開始匹配接下來的表示式。這就是所謂的前向否定斷言(逆序否定環視)。類似後向否定斷言,所包含的表示式必須是固定長度的字串。在前向否定斷言裡的表示式可能會在字串開始被搜尋。

(?(id/name)yes-pattern|no-pattern)
如果存在並捕獲成功指定編號或命名的捕獲組,就會嘗試匹配yes-pattern,如果捕獲失敗,那麼嘗試匹配no-pattern,|no- pattern是可省略的。例如,[(<)?(\
[email protected]
\w+(?:\.\w+)+)(?(1)>)]()是一個匹配電子郵件地址的表示式,將匹配 '<[email protected]>' 或者 '[email protected]'這樣的格式,但不匹配'<[email protected]'。該功能在2.4版本新加入。 元字元序列由'\'和下面列出的普通字元組成。如果字元不在下列,那麼正則將會匹配第二個字元,例如\$匹配'$'。 \number 引用對應編號的捕獲組的內容。組編號從1開始。例如,(.+) \1匹配的是'the the'或'55 55',但不匹配'the end'。注意反向引用所引用的內容。這個元字元序列只能用來引用1至99之間的一個,如果第一個數字為0,或者是三位數,它不會被解釋為反向引用,但會 作為8進位制數字。在字元組[]裡,所有的元字元都被視為字元。 \A 匹配字串的開始。 \b 匹配空字串(匹配位置比較容易理解),但只在單詞的開頭或結尾。一個單詞是由字母數字或下劃線字元組成,因此一個單詞的邊界是空白或者非字母 數字、不包括下劃線。請注意,\b是指\w和\W之間的邊界,因此確切的字符集定義取決於UNICODE和LOCALE編譯標誌的值。在字元範圍內,\b 表示退格符,與python的字串相容。 \B 匹配空字串(匹配位置比較容易理解),但當它不在單詞的開始或結尾。這是和\b相反的,也受到LOCALE和UNICODE的設定影響。 \d 當UNICODE標誌沒有指定,匹配任何10進位制數字,相當於[0-9]。帶UNICODE標誌時,它會匹配任何在unicode字符集中屬於數字分類的字元。 \D 當UNICODE標誌沒有指定,匹配任何非數字字元,相當於[^0-9]。帶UNICODE標誌時,它會匹配任何不在unicode字符集中屬於數字分類的字元。 \s 當LOCALE和UNICODE標誌沒有指定時,匹配任何空白字元,這相當於[ \t\n\r\f\v]。帶LOCALE標誌時,它將匹配當前環境定義的空白符。如果帶UNICODE標誌,那麼將匹配任何被劃分為空白符的符號。 \S 當LOCALE和UNICODE標誌沒有指定時,匹配任何非空白字元,這相當於[^\t\n\r\f\v]。帶LOCALE標誌時,它將匹配當前環境定義的非空白符。如果帶UNICODE標誌,那麼將匹配任何不被劃分為空白符的符號。 \w 當LOCALE和UNICODE標誌沒有指定時,匹配任何字母數字字元、下劃線,這相當於[a-zA-Z0-9_]。帶LOCALE標誌時,它 將匹配當前環境定義的字母和[0-9_]。帶UINCODE標誌時,將匹配在unicode字符集裡劃分為字母的字元和 [0-9_]。 \W 當LOCALE和UNICODE標誌沒有指定時,匹配任何非字母數字字元、下劃線,這相當於[^a-zA-Z0-9_]。帶LOCALE標誌 時,它將匹配除了當前環境定義的字母、[0-9_]。帶UINCODE標誌時,將匹配除了在unicode字符集裡劃分為字母的字元、[0-9_]。 \Z 匹配字串的結束。