python3之正則表達式

一、正則表達式基礎

正則表達式是用於處理字符串的強大工具,擁有本身獨特的語法以及一個獨立的處理引擎,效率上可能否則str自帶方法,但功能十分強大。python

正則表達式的大體匹配流程:依次拿出表達式和文本中的字符比較,若是每個字符都能匹配,則匹配成功;一旦有匹配不成功的字符則匹配失敗。正則表達式

python支持的正則表達式元字符和語法:工具

模式 描述
^ 匹配字符串的開頭
$ 匹配字符串的末尾。
. 匹配任意字符,除了換行符,當re.DOTALL標記被指定時,則能夠匹配包括換行符的任意字符。
[...] 用來表示一組字符,單獨列出:[amk] 匹配 'a','m'或'k'
[^...] 不在[]中的字符:[^abc] 匹配除了a,b,c以外的字符。
re* 匹配0個或多個的表達式。
re+ 匹配1個或多個的表達式。
re? 匹配0個或1個由前面的正則表達式定義的片斷,非貪婪方式
re{ n}  
re{ n,} 精確匹配n個前面表達式。
re{ n, m} 匹配 n 到 m 次由前面的正則表達式定義的片斷,貪婪方式
a| b 匹配a或b
(re) G匹配括號內的表達式,也表示一個組
(?imx) 正則表達式包含三種可選標誌:i, m, 或 x 。隻影響括號中的區域。
(?-imx) 正則表達式關閉 i, m, 或 x 可選標誌。隻影響括號中的區域。
(?: re) 相似 (...), 可是不表示一個組
(?imx: re) 在括號中使用i, m, 或 x 可選標誌
(?-imx: re) 在括號中不使用i, m, 或 x 可選標誌
(?#...) 註釋.
(?= re) 前向確定界定符。若是所含正則表達式,以 ... 表示,在當前位置成功匹配時成功,不然失敗。但一旦所含表達式已經嘗試,匹配引擎根本沒有提升;模式的剩餘部分還要嘗試界定符的右邊。
(?! re) 前向否認界定符。與確定界定符相反;當所含表達式不能在字符串當前位置匹配時成功
(?> re) 匹配的獨立模式,省去回溯。
\w 匹配字母數字及下劃線
\W 匹配非字母數字及下劃線
\s 匹配任意空白字符,等價於 [\t\n\r\f].
\S 匹配任意非空字符
\d 匹配任意數字,等價於 [0-9].
\D 匹配任意非數字
\A 匹配字符串開始
\Z 匹配字符串結束,若是是存在換行,只匹配到換行前的結束字符串。c
\z 匹配字符串結束
\G 匹配最後匹配完成的位置。
\b 匹配一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 能夠匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。
\B 匹配非單詞邊界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。
\n, \t, 等. 匹配一個換行符。匹配一個製表符。等
\1...\9 匹配第n個分組的內容。
\10 匹配第n個分組的內容,若是它經匹配。不然指的是八進制字符碼的表達式。

正則表達式修飾符-可選標誌spa

正則表達式能夠包含一些可選標誌修飾符來控制匹配的模式,修飾符被指定爲一個可選的標誌,多個標誌能夠經過按位or(|)來指定。3d

修飾符 描述
re.I 使匹配對大小寫不敏感
re.L 作本地化識別(locale-aware)匹配
re.M 多行匹配,影響 ^ 和 $
re.S 使 . 匹配包括換行在內的全部字符
re.U 根據Unicode字符集解析字符。這個標誌影響 \w, \W, \b, \B.
re.X 該標誌經過給予你更靈活的格式以便你將正則表達式寫得更易於理解。

二、re方法

python從1.5開始增長了re模塊,它提供了perl風格的正則表達式模式。code

re模塊使python語言擁有所有的正則表達式功能。對象

re模塊方法:blog

re.match索引

嘗試從字符串的起始位置匹配一個模式,若是不是起始位置匹配成功則返回none。ci

re.match語法:re.match(pattern,string,flags=0)

pattern:匹配的正則表達式,string:要匹配的字符串,flags:標誌位,用於控制正則表達式的匹配方式,如:是否區分大小寫,多行匹配等。

>>> import re
>>> print(re.match('abc','abcefg').group())  #匹配開頭,group方法返回分組字符串。
abc
>>> r1 = re.match('abc','1abcefg')
>>> print(r1)   #開頭未匹配到返回none
None

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

用於查找字符串中能夠匹配成功的子串,從string的開始位置匹配到結尾,匹配成功則返回一個匹配結果再也不向後匹配了,如匹配失敗則返回None。

>>> pattern = re.search('w','aw,bw,cw,dw')  #匹配結果
>>> print(pattern)  #返回一個match對象
<_sre.SRE_Match object at 0x7fcfa3566920>
>>> pattern.group()   #獲取一個分組截獲的字符串
'w'
>>> pattern.start()  #截獲字符串的開始索引
1
>>> pattern.end()  #截獲字符串的結束索引
2

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

按照可以匹配的字符串以列表的形式分隔返回不能匹配到的字串,maxsplit用於指定最大分割次數,不指定將所有分割。

>>> print(re.split('[0-9]','a1b2c3'))
['a', 'b', 'c', '']
#返回不能匹配的對象,以列表的形式

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

搜索string,以列表的形式返回所有能匹配到的字串。

>>> print(re.findall('[0-9]','a1b2c3'))
['1', '2', '3']
>>> print(re.findall('\d+','a21b32c35'))
['21', '32', '35']
#以列表的形式返回全部匹配的子串,\d+爲匹配1到多個數字

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

搜索string,返回訪問每個匹配結果的match對象的迭代器

>>> pat = re.finditer('\d+','aa123bb456cc')  #返回match對象的一個迭代器
>>> print(pat)
<callable_iterator object at 0x7fcfa354df10>
>>> for i in pat:     #循環迭代器取值
...   print(i.group())
... 
123
456

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

使用repl替換string中每個匹配的子串後返回替換後的字符串。count用於指定最多替換的次數,不知道時所有替換。

>>> pat = re.sub('\d+','@@@','aaa1bbb22ccc333')
>>> print(pat)   #替換匹配對象
aaa@@@bbb@@@ccc@@@
>>> print(re.sub('\d+','@@@','aaa1bbb22ccc333',count=2))
aaa@@@bbb@@@ccc333  #只替2次匹配到的子串

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

返回一個元組包含(新的替換字串,數量)

>>> print(re.subn('\d+','@@@','aaa1bbb22ccc333',count=2))
('aaa@@@bbb@@@ccc333', 2)
#返回repl替換的對象和替換的次數

re.compile(pattern,flags=0)

編譯一個正則表達式模式,返回一個模式對象

>>> import re
>>> re1 = re.compile(r'hello')   #編譯一個正則匹配模式
>>> print(type(re1))
<class '_sre.SRE_Pattern'>  #該模式是一個pattern對象
>>> print(re.match(re1,'hello world').group())
hello

三、match對象方法

patt = re.search('(\d+),(\d+)','11,3dsfdsa3324fdag4556'
>>> print(type(patt))  #返回一個match對象
<class '_sre.SRE_Match'>
#string匹配時使用的文本
>>> print(patt.string)   
11,3dsfdsa3324fdag4556
#re匹配時使用的正則模式(pattern對象)
>>> print(patt.re)
<_sre.SRE_Pattern object at 0x7fcfa3c4b530>
#regs返回分組索引
>>> print(patt.regs)
((0, 4), (0, 2), (3, 4))
#pos開始搜索的索引
>>> print(patt.pos)
0
#endpos結束搜索的索引
>>> print(patt.endpos)
22
#lastindex最後一個被捕獲的分組在文本中的索引
>>> print(patt.lastindex)
2
#lastindex最後一個捕獲的分組的別名,如沒有則返回None
>>> print(patt.lastgroup)
None
#group()得到一個或多個分組截獲的字符串
>>> print(patt.group())
11,3
#得到第1個分組的字符串
>>> print(patt.group(1))
11
>>> print(patt.group(2))
3
#groups()以元祖的形式返回所有分組截獲的字符串
>>> print(patt.groups())
('11', '3')
#groupdict()返回已有別名的組的別名爲健,以該組截獲的子串味值的字典
>>> print(patt.groupdict())
{}
#start()返回組截獲的子串在string中的起始索引
>>> print(patt.start())
0
>>> print(patt.start(1))
0
#返回第2個分組的起始索引
>>> print(patt.start(2))
3
#stop()返回組截獲的子串在string中的結束索引
>>> print(patt.end(2))
4
>>> print(patt.end(1))
2
#返回開始和結束的索引
>>> print(patt.span())
(0, 4)
#返回第1個分組的開始結束索引
>>> print(patt.span(1))
(0, 2)
>>> print(patt.span(2))
(3, 4)