python模組-re模組

-柚子皮-發表於2014-05-15

http://blog.csdn.net/pipisorry/article/details/25909899
Python除了 str 物件自帶的一些方法外,re文書處理能力也很強大。

正規表示式元字元說明

[python正規表示式]

匯入和檢視正規表示式模組

import re
檢視正規表示式模組方法
dir(re)
    [‘DEBUG’, ‘DOTALL’, ‘I’, ‘IGNORECASE’, ‘L’, ‘LOCALE’, ‘M’, ‘MULTILINE’, ‘S’, ‘Scanner’, ‘T’,’TEMPLATE’, ‘U’, ‘UNICODE’, ‘VERBOSE’, ‘X’, ‘_MAXCACHE’, ‘all‘, ‘builtins‘, ‘doc‘,’file‘, ‘name‘, ‘package‘, ‘version‘, ‘_alphanum’, ‘_cache’, ‘_cache_repl’,’_compile’, ‘_compile_repl’, ‘_expand’, ‘_pattern_type’, ‘_pickle’, ‘_subx’, ‘compile’,’copy_reg’, ‘error’, ‘escape’, ‘findall’, ‘finditer’, ‘match’, ‘purge’, ‘search’, ‘split’,’sre_compile’, ‘sre_parse’, ‘sub’, ‘subn’, ‘sys’, ‘template’]

提示:

1. 當我們不會用模組方法的時候用help

2. py2中pattern中的字串要和string的編碼一致,不然會找不到,這個經常出現。

正規表示式中使用原始字串

Raw string notation (r"text") keeps regular expressions sane. Without it,every backslash ('\') in a regular expression would have to be prefixed withanother one to escape it.

皮皮Blog



正規表示式語法

基本規則

‘[‘ ‘]’ 字符集合設定符

由一對方括號括起來的字元,表明一個字符集合,能夠匹配包含在其中的任意一個字元。比如 [abc123],表明字元’a’ ‘b’ ‘c’ ‘1’ ‘2’ ‘3’都符合它的要求。可以被匹配。
在’[‘ ‘]’中還可以通過 ’-‘ 減號來指定一個字符集合的範圍,比如可以用[a-zA-Z]來指定所以英文字母的大小寫,不可以把大小的順序顛倒了。
如果在’[‘ ‘]’裡面的開頭寫一個 ‘^’ 號,則表示取非,即在括號裡的字元都不匹配。如[^a-zA-Z]表明不匹配所有英文字母。但是如果 ‘^’不在開頭,則它就不再是表示取非,而表示其本身,如[a-z^A-Z]表明匹配所有的英文字母和字元’^’。

‘|’ 或規則

將兩個規則並列起來,以‘|’連線,表示只要滿足其中之一就可以匹配。比如
[a-zA-Z]|[0-9] 表示滿足數字或字母就可以匹配,這個規則等價於 [a-zA-Z0-9]
’|’要注意兩點:
第一, 它在’[‘ ‘]’之中不再表示或,而表示他本身的字元。如果要在’[‘ ‘]’外面表示一個’|’字元,必須用反斜槓引導,即 ’\|’ ;
第二, 它的有效範圍是它兩邊的整條規則,比如‘dog|cat’匹配的是‘dog’和’cat’,而不是’g’和’c’。如果想限定它的有效範圍,必需使用一個無捕獲組 ‘(?: )’包起來。比如要匹配 ‘I have a dog’或’I have a cat’,需要寫成r’I have a (?:dog|cat)’ ,而不能寫成 r’I have a dog|cat’,其中dog和cat是字串,不能是變數。
例:

s = ‘I have a dog , I have a cat’
re.findall( r’I have a (?:dog|cat)’ , s )
[‘I have a dog’, ‘I have a cat’] #正如我們所要的
下面再看看不用無捕獲組會是什麼後果:
re.findall( r’I have a dog|cat’ , s )
[‘I have a dog’, ‘cat’] #它將’I have a dog’ 和’cat’當成兩個規則了
至於無捕獲組的使用,後面將仔細說明。這裡先跳過。

‘.’ 匹配所有字元匹配除換行符’\n’外的所有字元

如果使用了=re.S選項,匹配包括’\n’的所有字元。
例:

s=’123 \n456 \n789’
findall(r‘.+’,s)
[‘123’, ‘456’, ‘789’]
re.findall(r‘.+’ , s , re.S)
[‘123\n456\n789’]

‘^’和’$’ 匹配字串開頭和結尾

注意’^’不能在‘[ ]’中,否則請看上面的’[‘ ‘]’說明。

在多行模式下,它們可以匹配每一行的行首和行尾。具體請看後面compile函式說明的’M’選項部分

‘\A’ 匹配字串開頭

匹配字串的開頭。它和’^’的區別是,’\A’只匹配整個字串的開頭(相當於單行模式),即使在’M’模式下,它也不會匹配其它行的行首。

‘\Z’ 匹配字串結尾

匹配字串的結尾。它和’$’的區別是,’\Z’只匹配整個字串的結尾,即使在’M’模式下,它也不會匹配其它各行的行尾。
例:

s= ‘12 34\n56 78\n90’
re.findall( r’^\d+’ , s , re.M ) #匹配位於行首的數字
[‘12’, ‘56’, ‘90’]
re.findall( r’\A\d+’, s , re.M ) #匹配位於字串開頭的數字
[‘12’]
re.findall( r’\d+$’ , s , re.M ) #匹配位於行尾的數字
[‘34’, ‘78’, ‘90’]
re.findall( r’\d+\Z’ , s , re.M ) #匹配位於字串尾的數字
[‘90’]

‘\d’ 匹配數字

’\d’表示匹配一個數字,即等價於[0-9]

‘\D’ 匹配非數字

匹配一個非數字的字元,等價於[^0-9]

‘\w’ 匹配字母和數字

匹配所有的英文字母和數字,即等價於[a-zA-Z0-9]。
‘\W’ 匹配非英文字母和數字
即’\w’的補集,等價於[^a-zA-Z0-9]。

‘\s’ 匹配間隔符

即匹配空格符、製表符、回車符等表示分隔意義的字元,它等價於[ \t\r\n\f\v]。(注意最前面有個空格)
‘\S’ 匹配非間隔符
即間隔符的補集,等價於[^ \t\r\n\f\v]

‘\b’ 匹配單詞邊界(相當於前向界定和後向界定)

它匹配一個單詞的邊界,比如空格等,不過它是一個‘0’長度字元,它匹配完的字串不會包括那個分界的字元。而如果用’\s’來匹配的話,則匹配出的字串中會包含那個分界符。
例:

s = ‘abc abcde bc bcd’
re.findall( r’\bbc\b’ , s ) #匹配一個單獨的單詞 ‘bc’ ,而當它是其它單詞的一部分的時候不匹配
[‘bc’] #只找到了那個單獨的’bc’
re.findall( r’\sbc\s’ , s ) #匹配一個單獨的單詞 ‘bc’
[’ bc ‘] #只找到那個單獨的’bc’,不過注意前後有兩個空格,可能有點看不清楚

‘\B’ 匹配非邊界

和’\b’相反,它只匹配非邊界的字元。它同樣是個0長度字元。

re.findall( r’\Bbc\w+’ , s ) #匹配包含’bc’但不以’bc’為開頭的單詞
[‘bcde’] #成功匹配了’abcde’中的’bcde’,而沒有匹配’bcd’

精確匹配和最小匹配

Python正則式還可以精確指定匹配的次數 :

1. ‘{m}’ 精確匹配m次; ‘{m,n}’ 匹配最少m次,最多n次。(n>m)

2. 如果你只想指定一個最少次數或只指定一個最多次數,你可以把另外一個引數空起來。比如你想指定最少3次,可以寫成 {3,} (注意那個逗號),同樣如果只想指定最大為5次,可以寫成{,5},也可以寫成{0,5}。

例 尋找下面字串中

a:3位數

b: 2位數到4位數

c: 5位數以上的數

d: 4位數以下的數

>>> s= ‘ 1 22 333 4444 55555 666666 ‘
>>> re.findall( r’\b\d{3}\b’ , s ) # a:3位數
['333']
>>> re.findall( r’\b\d{2,4}\b’ , s ) # b: 2位數到4位數
['22', '333', '4444']
>>> re.findall( r’\b\d{5,}\b’, s ) # c: 5位數以上的數
['55555', '666666']
>>> re.findall( r’\b\d{1,4}\b’ , s ) # 4位數以下的數
['1', '22', '333', '4444']

數量詞的貪婪模式與非貪婪模式 ‘*?’ ‘+?’ ‘??’ 最小匹配

正規表示式通常用於在文字中查詢匹配的字串。Python裡數量詞預設是貪婪的(在少數語言裡也可能是預設非貪婪),總是嘗試匹配儘可能多的字元;非貪婪的則相反,總是嘗試匹配儘可能少的字元。例如:正規表示式"ab*"如果用於查詢"abbbc",將找到"abbb"。而如果使用非貪婪的數量詞"ab*?",將找到"a"。[python正規表示式]

‘*’ ‘+’ ‘?’通常都是儘可能多的匹配字元。有時候我們希望它儘可能少的匹配。比如一個c語言的註釋 ‘/* part 1 */ /* part 2 */’,如果使用最大規則:

>>> s =r ‘/* part 1 */ code /* part 2 */’
>>> re.findall( r’/\*.*\*/’ , s )
[‘/* part 1 */ code /* part 2 */’]

結果把整個字串都包括進去了。如果把規則改寫成

>>> re.findall( r’/\*.*?\*/’ , s ) #在*後面加上?,表示儘可能少的匹配
['/* part 1 */', '/* part 2 */']

結果正確的匹配出了註釋裡的內容

‘(?:)’ 無捕獲組

當你要將一部分規則作為一個整體對它進行某些操作,比如指定其重複次數時,你需要將這部分規則用’(?:’ ‘)’把它包圍起來,而不能僅僅只用一對括號。
例:匹配字串中重複的’ab’

s=’ababab abbabb aabaab’
re.findall( r’\b(?:ab)+\b’ , s )
[‘ababab’]
如果僅使用一對括號: re.findall( r’\b(ab)+\b’ , s )
[‘ab’]
這是因為如果只使用一對括號,那麼這就成為了一個組(group)。

‘(?# )’ 註釋

Python允許你在正規表示式中寫入註釋,在’(?#’ ‘)’之間的內容將被忽略。

(?iLmsux) 編譯選項指定
Python的正則式可以指定一些選項,這個選項可以寫在findall或compile的引數中,也可以寫在正則式裡,成為正則式的一部分。這在某些情況下會便利一些。具體的選項含義請看後面的compile函式的說明。
此處編譯選項’i’ 等價於IGNORECASE ,L 等價於 LOCAL ,m 等價於 MULTILINE ,s 等價於 DOTALL ,u 等價於 UNICODE , x 等價於 VERBOSE 。
請注意它們的大小寫。在使用時可以只指定一部分,比如只指定忽略大小寫,可寫為 ‘(?i)’,要同時忽略大小寫並使用多行模式,可以寫為 ‘(?im)’。
另外要注意選項的有效範圍是整條規則,即寫在規則的任何地方,選項都會對全部整條正則式有效。

前向界定與後向界定

有時候需要匹配一個跟在特定內容後面的或者在特定內容前面的字串,Python提供一個簡便的前向界定和後向界定功能,或者叫前導指定和跟從指定功能。它們是:
‘(?<=…)’ 前向界定
括號中’…’代表你希望匹配的字串的前面應該出現的字串。
‘(?=…)’ 後向界定
括號中的’…’代表你希望匹配的字串後面應該出現的字串。
例: 你希望找出c語言的註釋中的內容,它們是包含在’/’和’/’之間,不過你並不希望匹配的結果把’/’和’/’也包括進來,那麼你可以這樣用:

s=r'/* comment 1 */ code /* comment 2 */'
print(re.findall(r'(?<=/\*).*?(?=\*/)', s))
[' comment 1 ', ' comment 2 ']

Note:

1. 注意這裡我們仍然使用了最小匹配,以避免把整個字串給匹配進去了。
2. 前向界定括號中的表示式必須是常值,也即你不可以在前向界定的括號裡寫正則式或者變數

比如你如果在下面的字串中想找到被字母夾在中間的數字,你不可以用前向界定:
s = ‘aaa111aaa , bbb222 , 333ccc ‘
re.findall( r’(?<=[a-z]+)\d+(?=[a-z]+)’ , s ) # 錯誤的用法
它會給出一個錯誤資訊:
error: look-behind requires fixed-width pattern

不過如果你只要找出後面接著有字母的數字,你可以在後向界定寫正則式

re.findall( r’\d+(?=[a-z]+)’, s )
[‘111’, ‘333’]
如果你一定要匹配包夾在字母中間的數字,你可以使用組(group)的方式
re.findall (r’[a-z]+(\d+)[a-z]+’ , s )
[‘111’]
組的使用將在後面詳細講解。

Note:小編皮建議用組()來代替

前向非界定和後向非界定

‘(?< !…)’前向非界定(<和!中間是沒有空格的,makedown編輯器會將部落格中的< !當成註釋不顯示, - -!給醉了。。。)
只有當你希望的字串前面不是’…’的內容時才匹配
‘(?!…)’後向非界定
只有當你希望的字串後面不跟著’…’內容時才匹配。
接上例,希望匹配後面不跟著字母的數字

re.findall( r’\d+(?!\w+)’ , s )
[‘222’]
注意這裡我們使用了\w而不是像上面那樣用[a-z],因為如果這樣寫的話,結果會是:
re.findall( r’\d+(?![a-z]+)’ , s )
[‘11’, ‘222’, ‘33’]
這和我們期望的似乎有點不一樣。它的原因,是因為’111’和’222’中的前兩個數字也是滿足這個要求的。因此可看出,正則式的使用還是要相當小心的,因為我開始就是這樣寫的,看到結果後才明白過來。不過Python試驗起來很方便,這也是指令碼語言的一大優點,可以一步一步的試驗,快速得到結果,而不用經過煩瑣的編譯、連結過程。也因此學習Python就要多試,跌跌撞撞的走過來,雖然曲折,卻也很有樂趣。

上面那些規則的話,還是有很多情況下會非常麻煩,比如使用前向界定和後向界定取夾在字母中間的數字的例子。用前面講過的規則都很難達到目的,但是用了組以後就很簡單了。

‘(‘’)’ 無命名組

最基本的組是由一對圓括號括起來的正則式。比如上面匹配包夾在字母中間的數字的例子中使用的(\d+),我們再回顧一下這個例子:

s = 'aaa111aaa , bbb222 , 333ccc '
print(re.findall (r'[a-z]+(\d+)[a-z]+' , s ) )
[‘111’] 
Note:findall函式只返回了包含在’()’中的內容,而雖然前面和後面的內容都匹配成功了,卻並不包含在結果中。

用組來實現前後向界定

s = 'dfidabc:dfidefdoildef'
pre = 'abc'
post = 'def'
patten = pre + '[::].+?' + post
answer = re.findall(patten, s)
print(answer)
['abc:dfidef']

Note:其中還用到了上面的最小匹配規則

‘(?P…)’ 命名組

‘(?P’代表這是一個Python的語法擴充套件’<…>’裡面是你給這個組起的名字,比如你可以給一個全部由數字組成的組叫做’num’,它的形式就是’(?P\d+)’ {’(?P<num>\d+)’吧}。起了名字之後,我們就可以在後面的正則式中通過名字呼叫這個組,它的形式是‘(?P=name)’ 呼叫已匹配的命名組。

要注意,再次呼叫的這個組是已被匹配的組,也就是說它裡面的內容是和前面命名組裡的內容是一樣的。

s=’aaa111aaa,bbb222,333ccc,444ddd444,555eee666,fff777ggg’
我們看看下面的正則式會返回什麼樣的結果:
re.findall( r’([a-z]+)\d+([a-z]+)’ , s ) # 找出中間夾有數字的字母
[(‘aaa’, ‘aaa’), (‘fff’, ‘ggg’)]
re.findall( r ‘(?P[a-z]+)\d+(?P=g1)’ , s ) #找出被中間夾有數字的前後同樣的字母
[‘aaa’]
re.findall( r’[a-z]+(/d+)([a-z]+)’ , s ) #找出前面有字母引導,中間是數字,後面是字母的字串中的中間的數字和後面的字母
[(‘111’, ‘aaa’), (‘777’, ‘ggg’)]

我們可以通過命名組的名字在後面呼叫已匹配的命名組,不過名字也不是必需的。

‘\number’ 通過序號呼叫已匹配的組

正則式中(並不能使用在sub函式中)的每個組都有一個序號,序號是按組從左到右,從1開始的數字,你可以通過下面的形式來呼叫已匹配的組
比如上面找出被中間夾有數字的前後同樣的字母的例子,也可以寫成:

re.findall( r’([a-z]+)\d+\1’ , s )
[‘aaa’]
結果是一樣的。
再看一個例子
s=’111aaa222aaa111 , 333bbb444bb33’
re.findall( r’(\d+)([a-z]+)(\d+)(\2)(\1)’ , s ) #找出完全對稱的 數字-字母-數字-字母-數字 中的數字和字母
[(‘111’, ‘aaa’, ‘222’, ‘aaa’, ‘111’)]

條件匹配功能(Python2.4以後的re模組)

‘(?(id/name)yes-pattern|no-pattern)’ 判斷指定組是否已匹配,執行相應的規則
這個規則的含義是,如果id/name指定的組在前面匹配成功了,則執行yes-pattern的正則式,否則執行no-pattern的正則式。
舉個例子,比如要匹配一些形如 usr@mail 的郵箱地址,不過有的寫成< usr@mail >即用一對<>括起來,有點則沒有,要匹配這兩種情況,可以這樣寫

>>> s=<usr1@mail1> usr2@maill2'
>>> re.findall( r'(<)?\s*(\w+@\w+)\s*(?(1)>)' , s )
[('<', 'usr1@mail1'), ('', 'usr2@maill2')]

不過如果目標字串如下

>>> s='<usr1@mail1>  usr2@maill2 <usr3@mail3   usr4@mail4>  < usr5@mail5  '

而你想得到要麼由一對<>包圍起來的一個郵件地址,要麼得到一個沒有被<>包圍起來的地址,但不想得到一對<>中間包圍的多個地址或不完整的<>中的地址,那麼使用這個式子並不能得到你想要的結果

>>> re.findall( r'(<)?\s*(\w+@\w+)\s*(?(1)>)' , s )
[('<', 'usr1@mail1'), ('', 'usr2@maill2'), ('', 'usr3@mail3'), ('', 'usr4@mail4'), ('', 'usr5@mail5')]

它仍然找到了所有的郵件地址。想要實現這個功能,單純的使用findall有點吃力,需要使用其它的一些函式,比如match或search函式,再配合一些控制功能。

[Regular Expression Syntax]

皮皮Blog



re模組常用的正規表示式處理函式Module Contents

Python正則庫API及正則選項

re選項

re庫API中,一般都有flags引數,通過該引數指定正規表示式選項。傳遞時一般使用簡寫,比如開啟DOTALL和MULTILINE使用re.I|re.M

A  ASCII       使\w\W\b\B\d\D匹配ASCII字元
I  IGNORECASE  忽略大小寫
L  LOCALE      使\w\W\b\B匹配本地字符集
M  MULTILINE   多行模式,"^" 匹配每行開頭,"$"匹配每行結尾
S  DOTALL      "." 匹配所有字元,包括"\n"
X  VERBOSE     詳細模式,忽略空白可以加入註釋
U  UNICODE     使\w\W\b\B\d\D匹配unicode字符集

API速查

這裡只是列出API,便於查閱,後面會詳細介紹API的使用。建議先跳過這一段,直接看後面的Sample,再回過頭來看這一段。

API分為三組,第一組是模組API(Module Contents),通過re.xx()使用;第二組是表示式API(Regular Expression Objects),re.complie()函式會返回一個表示式物件,通過該物件使用的函式;第三組是匹配物件API(Match Objects),像search這些函式都會返回一個匹配結果,這組API用於操作結果集。

re庫對於很多函式,例如match,都提供了兩種呼叫方式,一是直接通過re庫呼叫,將正規表示式作為引數,二是先用complie編譯表示式,通過返回的物件呼叫,方法二在正規表示式會被多次使用時會減少重複編譯花費的時間。

模組APII(Module Contents)

re.compile(pattern, flags=0)                預編譯一個正規表示式,返回一個表示式物件(Regular Expression Objects)
re.search(pattern, string, flags = 0)       在字串中找匹配的串,返回第一個匹配到的匹配物件
re.match(pattern, string, flags=0)          從頭開始匹配,返回匹配物件
re.split(pattern, string, maxsplit=0, flags=0)  使用pattern分割字串,返回一個結果list
re.findall(pattern, string, flags=0)        search加強版,返回所有的匹配物件的list
re.finditer(pattern, string, flags=0)       返回一個迭代器,使用者可以使用迭代器檢視所有匹配物件
re.sub(pattern, repl, string, count=0, flags=0)  使用repl替換string中pattern匹配到的部分;
                                                 這裡repl可以是一個函式,引數是匹配物件,返回要替代的串
re.subn(pattern, repl, string, count=0, flags=0) 類似sub,返回元組(new_string, number_of_subs_made)
re.escape(string)                           將所有的非字母數字字元前加"\"後返回
re.purge()                                  清空正規表示式快取

表示式API(Regular Expression Objects)
flags                                       編譯時的flag
groups                                      表示式中分組的數量
groupindex                                  以有別名的組別名為鍵、編號為值的字典
pattern                                     編譯時用的表示式字串
search(string[, pos[, endpos]])             從Pos處開始查詢字串,返回匹配物件
match(string[, pos[, endpos]])              從Pos處匹配字串,返回匹配物件
split(string, maxsplit=0)                   同re.split
findall(string[, pos[, endpos]])            從Pos處查詢所有匹配的字串,返回所有匹配物件的list
finditer(string[, pos[, endpos]])           從Pos處查詢所有的字串,返回一個迭代器
sub(repl, string, count=0)                  同re.sub
subn(repl, string, count=0)                 同re.subn

匹配物件API(Match Objects)
pos                     傳遞給函式的pos
endpos                  傳遞給函式的endpos
lastindex               最後一個捕獲的group的下標
lastgroup               最後一個捕獲的group的名字
re                      呼叫match或者search的表示式物件
string                  match或者search的字串
expand(template)        將匹配到的分組代入template中然後返回。template中可以使用\id或\g<id>、\g<name>引用分組
                        注意0不能使用,另外\10將被認為是第10個分組,如果你想表達\1之後是字元'0',只能使用\g<1>0。
group([group1, ...])    獲得一個或多個分組截獲的字串;指定多個引數時將以元組形式返回,0代表整個匹配串
groups([default])       以元組形式返回全部分組截獲的字串,相當於呼叫group((1,2,…n))
groupdict([default])    返回以有別名的組的別名為鍵、以該組截獲的子串為值的字典
start([group])          返回指定組的串在原串中的起始索引
end([group])            返回指定組的串在原串中的結束索引
span([group])           返回(start(group), end(group))

[基於Python官方手冊的翻譯和整理]

Match Object物件擁有的方法

1.group([group1,…])

  返回匹配到的一個或者多個子組。如果是一個引數,那麼結果就是一個字串,如果是多個引數,那麼結果就是一個引數一個item的元組。group1的預設值為0(將返回所有的匹配值).如果groupN引數為0,相對應的返回值就是全部匹配的字串,如果group1的值是[1…99]範圍之內的,那麼將匹配對應括號組的字串。如果組號是負的或者比pattern中定義的組號大,那麼將丟擲IndexError異常。如果pattern沒有匹配到,但是group匹配到了,那麼group的值也為None。如果一個pattern可以匹配多個,那麼組對應的是樣式匹配的最後一個。另外,子組是根據括號從左向右來進行區分的。
 >m=re.match(“(\w+) (\w+)”,”abcd efgh, chaj”)
 >m.group() # 匹配全部
 ‘abcd efgh’
 >m.group(1) # 第一個括號的子組.
 ‘abcd’
 >m.group(2)
 ‘efgh’
 >m.group(1,2) # 多個引數返回一個元組
 (‘abcd’, ‘efgh’)
 >m=re.match("(?P<first_name>\w+) (?P<last_name>\w+)","sam lee")

m.group(“first_name”) #使用group獲取含有name的子組
‘sam’
m.group(“last_name”)
‘lee’

 下面把括號去掉
 >m=re.match(“\w+ \w+”,”abcd efgh, chaj”)
 >m.group()
 ‘abcd efgh’
 >m.group(1)
 Traceback (most recent call last):
File “pyshell#32>”, line 1, in
m.group(1)
 IndexError: no such group

 If a group matches multiple times, only the last match is accessible:
如果一個組匹配多個,那麼僅僅返回匹配的最後一個的。
 >m=re.match(r”(..)+”,”a1b2c3”)
 >m.group(1)
 ‘c3’
 >m.group()
 ‘a1b2c3’
 Group的預設值為0,返回正規表示式pattern匹配到的字串

 >s=”afkak1aafal12345adadsfa”
 >pattern=r”(\d)\w+(\d{2})\w”
 >m=re.match(pattern,s)
 >print m
 None
 >m=re.search(pattern,s)
 >m
 <_sre.SRE_Match object at 0x00C2FDA0>
 >m.group()
 ‘1aafal12345a’
 >m.group(1)
 ‘1’
 >m.group(2)
 ‘45’
 >m.group(1,2,0)
 (‘1’, ‘45’, ‘1aafal12345a’)

2.groups([default])

 返回一個包含所有子組的元組。Default是用來設定沒有匹配到組的預設值的。Default預設是”None”,
 >m=re.match(“(\d+).(\d+)”,”23.123”)
 >m.groups()
 (‘23’, ‘123’)
 >m=re.match(“(\d+).?(\d+)?”,”24”) #這裡的第二個\d沒有匹配到,使用預設值”None”
 >m.groups()
 (‘24’, None)
 >m.groups(“0”)
 (‘24’, ‘0’)

3.groupdict([default])

 返回匹配到的所有命名子組的字典。Key是name值,value是匹配到的值。引數default是沒有匹配到的子組的預設值。這裡與groups()方法的引數是一樣的。預設值為None
 >m=re.match(“(\w+) (\w+)”,”hello world”)
 >m.groupdict()
 {}
 >m=re.match(“(?P\w+) (?P\w+)”,”hello world”)
 >m.groupdict()
 {‘secode’: ‘world’, ‘first’: ‘hello’}
通過上例可以看出,groupdict()對沒有name的子組不起作用

[Match Objects]

re常用模組

re.compile(pattern, flags=0)

re.compile 可以把正規表示式編譯成一個正則物件。可以把那些經常使用的正規表示式編譯成正規表示式物件,這樣可以提高一定的效率。

Compile a regular expression pattern into a regular expression object, whichcan be used for matching using its match() andsearch() methods.

help(re.compile)
compile(pattern, flags=0)

第一個引數:規則
第二個引數:標誌位
例項:

test=”Hi, nice to meet you where are you from?”
k=re.compile(r’\w*o\w*’) #匹配帶o的字串
dir(k)
[‘copy‘, ‘deepcopy‘, ‘findall’, ‘finditer’, ‘match’, ‘scanner’, ‘search’, ‘split’,’sub’, ‘subn’]
print k.findall(test) #顯示所有包涵o的字串
[‘to’, ‘you’, ‘you’, ‘from’]
print k.sub(lambdam: ‘[‘+m.group(0) +’]’,test) # 將字串中含有o的單詞用[]括起來
Hi, nice [to] meet [you] where are [you] [from]?

[Regular Expression Objects]

re.search(pattern, string, flags=0)

re.search 函式會在字串內查詢模式匹配,直到找到第一個匹配然後返回一個物件k。return a corresponding match object.

k.group(0)代表整個匹配模式對應的字串,k.group(1)代表匹配模式中的組對應的字串

如果字串沒有匹配,則返回None。

help(re.search)
search(pattern, string, flags=0)
第一個引數:規則
第二個引數:表示要匹配的字串
第三個引數:標緻位,用於控制正規表示式的匹配方式


例項:下面的例子kuangl
name=”Hello,My name is kuangl,nice to meet you…”
k=re.search(r’k(uan)gl’,name)
if k:
… print k.group(0),k.group(1)
… else:
… print ”Sorry,not search!”

kuangl uan

re.match(pattern, string, flags=0)

re.match 嘗試從字串的開始匹配一個模式,也等於說是匹配第一個單詞。return a corresponding match object.

help(re.match)
match(pattern, string, flags=0)

第一個引數:規則
第二個引數:表示要匹配的字串
第三個引數:標緻位,用於控制正規表示式的匹配方式 

例項1:下面的例子匹配Hello單詞

name=”Hello,My name is kuangl,nice to meet you…”
k=re.match(r”(\H….)”,name)
if k:
… print k.group(0),’\n’,k.group(1)
… else:
… print “Sorry,not match!”

Hello
Hello

re.match與re.search的區別:re.match只匹配字串的開始,如果字串開始不符合正規表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配。

例項2:判斷字串i是否是一個數字串

if re.match('\d+', i)

re.split(pattern, string, maxsplit=0, flags=0)

re.split 用於來分割字串

help(re.split)
split(pattern, string, maxsplit=0)

第一個引數:規則
第二個引數:字串
第三個引數:最大分割字串,預設為0,表示每個匹配項都分割
例項:分割所有的字串

test=”Hi, nice to meet you where are you from?” 
re.split(r”\s+”,test) 
[‘Hi,’, ‘nice’, ‘to’, ‘meet’, ‘you’, ‘where’, ‘are’, ‘you’, ‘from?’] 
re.split(r”\s+”,test,3) #分割前三個 
[‘Hi,’, ‘nice’, ‘to’, ‘meet you where are you from?’]

python使用多個分隔符分割字串

下面是使用漢語標點符號[。!?,]和英文標點符號[!?,]以及微博轉發符號“//@”作為斷句的分隔符的示例

line = '地丁 一。雪!地陪?霜 ,阿!地?地址,鄄鄄//@村鄄李'
print(re.split(r'[。!?,!?,]|//@', line))
['地丁 一', '雪', '地陪', '霜 ', '阿', '地', '地址', '鄄鄄', '村鄄李']

re.findall(pattern, string, flags=0)

re.findall 在目標字串查詢符合規則的字串

help(re.findall)
findall(pattern, string, flags=0)

第一個引數:規則
第二個引數:目標字串
但三個引數:後面還可以跟一個規則選擇項
返回的結果是一個列表(如果有括號()分組,則只返回所有分組的列表),列表中存放的是符合規則的字串,如果沒有符合規則的字串找到,就會返回一個空值。

例項:查詢郵件賬號

mail=’user01@mail.comuser02@mail.com user04@mail.com’#第3個故意沒有尖括號
re.findall(r’(\w+@m….[a-z]{3})’,mail)
[‘user01@mail.com’, ‘user02@mail.com’, ‘user04@mail.com’]

例項2:

post_ori_text = r'sinaSSOController.preloginCallBack({"retcode":0,"servertime":1441512360,"pcid":"gz-da3c627b7b8260ba5cfd453f4eb3347ca01f","nonce":"9OZ4S7","pubkey":
"EB2A385686618****","rsakv":"1330428213","exectime":3})'
re.findall('{"retcode":(.*?),"servertime":(.*?),"pcid":"(.*?)","nonce":"(.*?)","pubkey":"(.*?)","rsakv":"(.*?)","exectime":(.*?)}', post_ori_text, re.I)[0]
上面 的結果為(u'0', u'1441512470', u'gz-eae72a8b0f6be469f4ac627ca38f7069d5c5', u'D2HXK0', u'EB2A38568661887FA18******', u'1330428213', u'2')

re.sub(pattern, repl, string, count=0, flags=0)

re.sub 用於替換字串的匹配項。If the pattern isn’t found,string is returned unchanged.

第一個引數:規則
第二個引數:替換後的字串
第三個引數:字串
第四個引數:替換個數。預設為0,表示每個匹配項都替換

第二個引數:repl
repl,就是replacement,被替換的字串的意思。repl可以是字串,也可以是函式。
repl是字串
如果repl是字串的話,其中的任何反斜槓轉義字元,都會被處理的。
\n:會被處理為對應的換行符;
\r:會被處理為回車符;
其他不能識別的轉移字元,則只是被識別為普通的字元:
比如\j,會被處理為j這個字母本身;
反斜槓加g以及中括號內一個名字,即:\g<name>,對應著命了名的組,named group

repl是函式

import re;
def pythonReSubDemo():
    inputStr = "hello 123 world 456";
     
    def _add111(matched):
        intValue = int(matched.group("number"))
        return str(intValue + 111)
        
    replacedStr = re.sub("(?P<number>\d+)", _add111, inputStr);
    print replacedStr

    #hello 234 world 567

In string-type repl arguments, in addition to the character escapes andbackreferences described above,\g<name> will use the substring matched by the group named name, asdefined by the (?P<name>...) syntax. \g<number> uses the correspondinggroup number; \g<2> is therefore equivalent to \2, but isn’t ambiguousin a replacement such as \g<2>0. \20 would be interpreted as areference to group 20, not a reference to group 2 followed by the literalcharacter '0'. The backreference \g<0> substitutes in the entiresubstring matched by the RE.

示例(使用組和原始字串)

import os
import re

origin_str = '..bin/clang -g  -DUNDEF_THREADS_HACK -c -o chared.o chared.c'
dir = 'path'
new_str = re.sub('-c', '-emit-llvm -c', origin_str)
new_str = re.sub('(-o\s*)(.*?\.o)', r'\1' + os.path.join(dir, r'\2') + '.bc', new_str)
print(new_str)
../bin/clang -g  -DUNDEF_THREADS_HACK -emit-llvm -c -o path/chared.o.bc chared.c

[re.sub(pattern, repl, string, count=0, flags=0)]

[詳解Python中re.sub]

re.subn(pattern, repl, string, count=0, flags=0)

Perform the same operation as sub(), but return a tuple (new_string,number_of_subs_made).

皮皮Blog


re其它部分

Simulating scanf()

Python does not currently have an equivalent to scanf(). Regularexpressions are generally more powerful, though also more verbose, thanscanf() format strings. The table below offers some more-or-lessequivalent mappings between scanf() format tokens and regularexpressions.

scanf() TokenRegular Expression
%c.
%5c.{5}
%d[-+]?\d+
%e, %E, %f, %g[-+]?(\d+(\.\d*)?|\.\d+)([eE][-+]?\d+)?
%i[-+]?(0[xX][\dA-Fa-f]+|0[0-7]*|\d+)
%o[-+]?[0-7]+
%s\S+
%u\d+
%x, %X[-+]?(0[xX])?[\dA-Fa-f]+

[Simulating scanf()]

from:http://blog.csdn.net/pipisorry/article/details/25909899

ref: [re — Regular expression operations]

萬用字元和正規表示式

Python正則式的基本用法


相關文章