Python3 正則表示式
正則表示式是一個特殊的字元序列,它能幫助你方便的檢查一個字串是否與某種模式匹配。
Python 自1.5版本起增加了re 模組,它提供 Perl 風格的正則表示式模式。
re 模組使 Python 語言擁有全部的正則表示式功能。
compile 函式根據一個模式字串和可選的標誌引數生成一個正則表示式物件。該物件擁有一系列方法用於正則表示式匹配和替換。
re 模組也提供了與這些方法功能完全一致的函式,這些函式使用一個模式字串做為它們的第一個引數。
本章節主要介紹 Python 中常用的正則表示式處理函式,如果你對正則表示式不瞭解,可以去學習正則表示式 - 教程。
1.re.match函式
re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。
函式語法:
re.match(pattern, string, flags=0)
函式引數說明:
匹配成功re.match方法返回一個匹配的物件,否則返回None。
我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式。
import re print(re.match('www', 'www.google.com').span()) # 在起始位置匹配 print(re.match('com', 'www.google.com')) # 不在起始位置匹配 以上例項執行輸出結果為: (0, 3) None
#!/usr/bin/python3 import re line = "Cats are smarter than dogs" # .* 表示任意匹配除換行符(\n、\r)之外的任何單個或多個字元 # (.*?) 表示"非貪婪"模式,只儲存第一個匹配到的子串 matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I) #re.M在正則表示式修飾符 - 可選標誌章節會講解到。 if matchObj: print ("matchObj.group() :", matchObj.group()) print ("matchObj.group(1) : ", matchObj.group(1)) print ("matchObj.group(2) : ", matchObj.group(2)) else: print ("No match!!") 以上例項執行結果如下: matchObj.group() : Cats are smarter than dogs matchObj.group(1) : Cats matchObj.group(2) : smarter
2.re.search方法
re.search 掃描整個字串並返回第一個成功的匹配。
函式語法:
re.search(pattern, string, flags=0)
函式引數說明:
匹配成功re.search方法返回一個匹配的物件,否則返回None。
我們可以使用group(num) 或 groups() 匹配物件函式來獲取匹配表示式。
import re print(re.search('www', 'www.google.com').span()) # 在起始位置匹配 print(re.search('com', 'www.google.com').span()) # 不在起始位置匹配 以上結果輸出為: (0, 3) (11, 14)
#!/usr/bin/python3 import re line = "Cats are smarter than dogs" searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I) if searchObj: print ("searchObj.group() : ", searchObj.group()) print ("searchObj.group(1) : ", searchObj.group(1)) print ("searchObj.group(2) : ", searchObj.group(2)) else: print ("Nothing found!!") 以上例項執行結果如下: searchObj.group() : Cats are smarter than dogs searchObj.group(1) : Cats searchObj.group(2) : smarter
3.re.match與re.search的區別
re.match 只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回 None,而 re.search 匹配整個字串,直到找到一個匹配。
#!/usr/bin/python3 import re line = "Cats are smarter than dogs" matchObj = re.match( r'dogs', line, re.M|re.I) if matchObj: print ("match --> matchObj.group() : ", matchObj.group()) else: print ("No match!!") matchObj = re.search( r'dogs', line, re.M|re.I) if matchObj: print ("search --> matchObj.group() : ", matchObj.group()) else: print ("No match!!") 以上例項執行結果如下: No match!! search --> matchObj.group() : dogs
4.檢索和替換
Python 的re模組提供了re.sub用於替換字串中的匹配項。
語法:
re.sub(pattern, repl, string, count=0, flags=0)
引數:
- pattern : 正則中的模式字串。
- repl : 替換的字串,也可為一個函式。
- string : 要被查詢替換的原始字串。
- count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。
- flags : 編譯時用的匹配模式,數字形式。
前三個為必選引數,後兩個為可選引數。
#!/usr/bin/python3 import re phone = "2004-959-559 # 這是一個電話號碼" # 刪除註釋 num = re.sub(r'#.*$', "", phone) print ("電話號碼 : ", num) # 移除非數字的內容 num = re.sub(r'\D', "", phone) print ("電話號碼 : ", num) 以上例項執行結果如下: 電話號碼 : 2004-959-559 電話號碼 : 2004959559
4.1 repl 引數是一個函式
以下例項中將字串中的匹配的數字乘於 2:
#!/usr/bin/python import re # 將匹配的數字乘於 2 def double(matched): value = int(matched.group('value')) return str(value * 2) s = 'A23G4HFD567' print(re.sub('(?P<value>\d+)', double, s)) 執行輸出結果為: A46G8HFD1134
4.2 compile 函式
compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,供 match() 和 search() 這兩個函式使用。
語法格式為:
re.compile(pattern[, flags])
引數:
- pattern : 一個字串形式的正則表示式
- flags 可選,表示匹配模式,比如忽略大小寫,多行模式等,具體引數為:
-
re.I 忽略大小寫
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴於當前環境
- re.M 多行模式
- re.S 即為' . '並且包括換行符在內的任意字元(' . '不包括換行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴於 Unicode 字元屬性資料庫
- re.X 為了增加可讀性,忽略空格和' # '後面的註釋
>>>import re >>> pattern = re.compile(r'\d+') # 用於匹配至少一個數字 >>> m = pattern.match('one12twothree34four') # 查詢頭部,沒有匹配 >>> print( m ) None >>> m = pattern.match('one12twothree34four', 2, 10) # 從'e'的位置開始匹配,沒有匹配 >>> print( m ) None >>> m = pattern.match('one12twothree34four', 3, 10) # 從'1'的位置開始匹配,正好匹配 >>> print( m ) # 返回一個 Match 物件 <_sre.SRE_Match object at 0x10a42aac0> >>> m.group(0) # 可省略 0 '12' >>> m.start(0) # 可省略 0 3 >>> m.end(0) # 可省略 0 5 >>> m.span(0) # 可省略 0 (3, 5)
在上面,當匹配成功時返回一個 Match 物件,其中:
- group([group1, …]) 方法用於獲得一個或多個分組匹配的字串,當要獲得整個匹配的子串時,可直接使用 group() 或 group(0);
- start([group]) 方法用於獲取分組匹配的子串在整個字串中的起始位置(子串第一個字元的索引),引數預設值為 0;
- end([group]) 方法用於獲取分組匹配的子串在整個字串中的結束位置(子串最後一個字元的索引+1),引數預設值為 0;
- span([group]) 方法返回 (start(group), end(group))。
再看看一個例子:
>>>import re >>> pattern = re.compile(r'([a-z]+) ([a-z]+)', re.I) # re.I 表示忽略大小寫 >>> m = pattern.match('Hello World Wide Web') >>> print( m ) # 匹配成功,返回一個 Match 物件 <_sre.SRE_Match object at 0x10bea83e8> >>> m.group(0) # 返回匹配成功的整個子串 'Hello World' >>> m.span(0) # 返回匹配成功的整個子串的索引 (0, 11) >>> m.group(1) # 返回第一個分組匹配成功的子串 'Hello' >>> m.span(1) # 返回第一個分組匹配成功的子串的索引 (0, 5) >>> m.group(2) # 返回第二個分組匹配成功的子串 'World' >>> m.span(2) # 返回第二個分組匹配成功的子串索引 (6, 11) >>> m.groups() # 等價於 (m.group(1), m.group(2), ...) ('Hello', 'World') >>> m.group(3) # 不存在第三個分組 Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group
4.3 findall
在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果有多個匹配模式,則返回元組列表,如果沒有找到匹配的,則返回空列表。
注意:match 和 search 是匹配一次, findall 匹配所有。
語法格式為:
re.findall(pattern, string, flags=0)
或
pattern.findall(string[, pos[, endpos]])
引數:
- pattern 匹配模式。
- string 待匹配的字串。
- pos 可選引數,指定字串的起始位置,預設為 0。
- endpos 可選引數,指定字串的結束位置,預設為字串的長度。
查詢字串中的所有數字:
import re result1 = re.findall(r'\d+','lizexiong 123 google 456') pattern = re.compile(r'\d+') # 查詢數字 result2 = pattern.findall('lizexiong 123 google 456') result3 = pattern.findall('lize88xiong123google456', 0, 15) print(result1) print(result2) print(result3) 結果輸出為: ['123', '456'] ['123', '456'] ['88', '123']
多個匹配模式,返回元組列表:
import re result = re.findall(r'(\w+)=(\d+)', 'set width=20 and height=10') print(result) [('width', '20'), ('height', '10')]
4.4 re.finditer
和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回。
re.finditer(pattern, string, flags=0)
引數:
import re it = re.finditer(r"\d+","12a32bc43jf3") for match in it: print (match.group() ) 輸出結果: 12 32 43 3
4.5 re.split
split 方法按照能夠匹配的子串將字串分割後返回列表,它的使用形式如下:
re.split(pattern, string[, maxsplit=0, flags=0])
引數:
>>>import re >>> re.split('\W+', 'google, google, google.') ['google', 'google', 'google', ''] >>> re.split('(\W+)', ' google, google, google.') ['', ' ', 'google', ', ', 'google', ', ', 'google', '.', ''] >>> re.split('\W+', ' google, google, google.', 1) ['', 'google, google, google.'] >>> re.split('a*', 'hello world') # 對於一個找不到匹配的字串而言,split 不會對其作出分割 ['hello world']
5.正則表示式物件
re.RegexObject
re.compile() 返回 RegexObject 物件。
re.MatchObject
group() 返回被 RE 匹配的字串。
-
- start() 返回匹配開始的位置
- end() 返回匹配結束的位置
- span() 返回一個元組包含匹配 (開始,結束) 的位置
6.正則表示式修飾符 - 可選標誌
正則表示式可以包含一些可選標誌修飾符來控制匹配的模式。修飾符被指定為一個可選的標誌。多個標誌可以通過按位 OR(|) 它們來指定。如 re.I | re.M 被設定成 I 和 M 標誌:
7.正則表示式模式
模式字串使用特殊的語法來表示一個正則表示式。
字母和數字表示他們自身。一個正則表示式模式中的字母和數字匹配同樣的字串。
多數字母和數字前加一個反斜槓時會擁有不同的含義。
標點符號只有被轉義時才匹配自身,否則它們表示特殊的含義。
反斜槓本身需要使用反斜槓轉義。
由於正則表示式通常都包含反斜槓,所以你最好使用原始字串來表示它們。模式元素(如 r'\t',等價於 \\t )匹配相應的特殊字元。
下表列出了正則表示式模式語法中的特殊元素。如果你使用模式的同時提供了可選的標誌引數,某些模式元素的含義會改變。
8.正則表示式例項