Python 正則表達式(Regex)

這裏寫圖片描述
這裏寫圖片描述
(1)* :是指字符匹配0次或者無限次,也就是說當某個字符出現一次或者無限次是 ==+,只有當 前面的字符可以不出現時,*!=+;加號(+)前面的字符最少出現一次
(2) 對於貪婪模式和非貪婪模式:? +? ?? 表示的意思是儘可能的少匹配或者不匹配前一個字符,具體可以匹配的次數還是與原來+?的定義一致。比如:ma =re.match(r’[0-9][a-z]*?’)就是儘量不去匹配最後一個[a-z]字符

這裏寫圖片描述

正則表達式使用反斜槓" \ "來代表特殊形式或用作轉義字符,這裏跟Python的語法衝突,因此,Python用" \\\\ "表示正則表達式中的" \ ",因爲正則表達式中如果要匹配" \ ",需要用\來轉義,變成" \\ ",而Python語法中又需要對字符串中每一個\進行轉義,所以就變成了" \\\\ "。

上面的寫法是不是覺得很麻煩,爲了使正則表達式具有更好的可讀性,Python特別設計了原始字符串(raw string),需要提醒你的是,在寫文件路徑的時候就不要使用raw string了,這裏存在陷阱。raw string就是用'r'作爲字符串的前綴,如 r"\n":表示兩個字符"\"和"n",而不是換行符了。Python中寫正則表達式時推薦使用這種形式。

絕大多數正則表達式操作與 模塊級函數或RegexObject方法 一樣都能達到同樣的目的。而且不需要你一開始就編譯正則表達式對象,但是不能使用一些實用的微調參數。

martch和search的區別

Python提供了兩種不同的原始操作:match和search。match是從字符串的起點開始做匹配,而search(perl默認)是從字符串做任意匹配。

編譯標誌

編譯標誌讓你可以修改正則表達式的一些運行方式。在 re 模塊中標誌可以使用兩個名字,一個是全名如 IGNORECASE,一個是縮寫,一字母形式如 I。(如果你熟悉 Perl 的模式修改,一字母形式使用同樣的字母;例如 re.VERBOSE的縮寫形式是 re.X。)多個標誌可以通過按位 OR-ing 它們來指定。如 re.I | re.M 被設置成 I 和 M 標誌:

I
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,這些註釋會被引擎忽略;註釋用 "#"號 來標識,不過該符號不能在字符串或反斜槓之後。

最後:如果能用字符串的方法,就不要選擇正則表達式,因爲字符串方法更簡單快速。

————————-追加更新———————–

包括以下元字符:
.
(Dot)在默認模式下,它匹配除了換行符號以外的任意字符。如果指定了DOTALL,那它將可匹配換行符。

^
(Caret)匹配字符串的開始,即物理行的開始,在多行模式下,也可匹配換行符後的位置,即邏輯行的開始。

$
匹配字符串的結尾或在字符串尾部的換行符之前的位置,在多行模式下,還可以匹配到一個新的行之前的位置。foo可以匹配’foo’和’foobar’,而foo$只匹配’foo’。更有趣的是,在’foo1\nfoo2\n’中搜索foo.$,默認模式下匹配到’foo2’,而在多行模式下,可匹配到’foo1’和’foo2’。不指定多行模式,$匹配物理行的結尾,而foo1爲串的邏輯行之前的字符,所以未被匹配。

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

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

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

*?、+?、??
使用”“、”+”、”?”這些量詞描述符都是貪婪匹配的,它們會匹配儘可能多的字符。有時,這種行爲並非是我們想要的,若使用<.>去匹配’”<\H1>title”’,它將會匹配整個字符串,而不只是’‘。在量詞描述符後面添加”?”後,會使匹配過程裏,變爲非貪婪模式,匹配儘可能少的字符。使用<.*?>去匹配之前的字符串,將只匹配<\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]akm ’裏的其中一個字符;[a-z]將匹配所有小寫字母,[a-zA-Z0-9]將匹配所有字母和數字;簡寫標記也可以在字符組裏描述。如果你想包含’]’或者’-‘,那就在該字符前使用反斜杆轉義,或者將它寫在字符組的第一個,例如[]]匹配’]’,注意,假如同時需要匹配’-‘和’]’,就只能把其中一個放在第一位,另一個用反斜杆轉義,推薦對所有不需要的元字符都使用反斜杆轉義。您還可以匹配一個除了字符組裏描述字符以外的字符,以脫字符’^’作爲第一個字符,將標示這是一個排除型字符組,^在別的位置,只會匹配普通的’^’字符。例如,[^5]匹配除了5以外的字符;[^^]匹配除了脫字符以外的字符。

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

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

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

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

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

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

m = re.match(‘a(?Pb)cde’,’abcde’) #命名捕獲組id捕獲b
m.group() #獲取所有成功匹配內容
‘abcde’
m.group(‘id’) #獲取id組捕獲內容
‘b’
m.end(‘id’) #獲取id組成功匹配結束位置點
2
m.end() #獲取整個表達式成功匹配結束位置點
5
m = re.match(‘a(?Pb)cde(?P=id)’,’abcdeb’) #反向引用了id組
m.group()
‘abcdeb’
re.sub(‘a(?Pb)cde(?P=id)’,’ab\gh’,’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()是從字符串開頭進行匹配,否則失敗,而使用環視功能會導致該函數失敗:

import re
m = re.search(‘(?<=abc)def’, ‘abcdef’)
m.group(0)
‘def’

This example looks for a word following a hyphen:

m = re.search(‘(?<=-)\w+’, ‘spam-egg’)
m.group(0)
‘egg’

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

(?(id/name)yes-pattern|no-pattern)
如果存在並捕獲成功指定編號或命名的捕獲組,就會嘗試匹配yes-pattern,如果捕獲失敗,那麼嘗試匹配no-pattern,|no-pattern是可省略的。例如,(<)?(\w+@\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
匹配字符串的結束

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章