在python中使用正則表示式
在python中通過內建的re庫來使用正則表示式,它提供了所有正則表示式的功能。
一、寫在前面:關於轉義的問題
正則表示式中用“\”表示轉義,而python中也用“\”表示轉義,當遇到特殊字元需要轉義時,你要花費心思到底需要幾個“\”,所以為了避免這個情況,強烈推薦使用原生字串型別(raw string)來書寫正則表示式。
方法很簡單,只需要在表示式前面加個“r”即可,如下:
r'\d{2}-\d{8}'
r'\bt\w*\b'
二、Re庫常用的功能函式
1. re.match()
從字串的起始位置匹配,匹配成功,返回一個匹配的物件,否則返回None
語法:re.match(pattern, string, flags=0)
pattern:匹配的正則表示式
string:要匹配的字串
flags:標誌位,用於控制正則表示式的匹配方式,如:是否區分大小寫,多行匹配等等;flags=0表示不進行特殊指定
可選標誌如下:
修飾符被指定為一個可選的標誌。多個標誌可以通過按位 OR(|) 它們來指定。如 re.I | re.M 被設定成 I 和 M 標誌
示例:
不含標誌位: >>> re.match(r'\d{2}','123') <_sre.SRE_Match object; span=(0, 2), match='12'> >>> re.match(r'\d{2}','ab123') >>> print(re.match(r'\d{2}','ab123')) None 含有標誌位: >>> re.match(r'a','ab123').group() 'a' >>> re.match(r'a','Ab123').group() Traceback (most recent call last): File "<pyshell#5>", line 1, in <module> re.match(r'a','Ab123').group() AttributeError: 'NoneType' object has no attribute 'group' >>> re.match(r'a','Ab123',re.I).group() 'A'
2. re.search()
掃描整個字串並返回第一個成功的匹配物件,否則返回None
語法:re.search(pattern, string, flags=0)
示例:
>>> re.search(r'\d{2}','Ab123')<_sre.SRE_Match object; span=(2, 4), match='12'> >>> re.search(r'\d{2}','Abcde') >>> print(re.search(r'\d{2}','Abcde')) None
可以看到match()和search()返回的時match物件(即匹配物件),可以通過group()方法獲得匹配內容
>>> re.search(r'\d{2}','Ab12c34d56e78').group()
'12'
>>> re.match(r'\d{2}','12c34d56e78').group(0)
'12'
group() 同group(0)就是匹配正則表示式整體結果,也就是所有匹配到的字元
group()其實更多的結合分組來使用,即如果在正則表示式中定義了分組(什麼是分組?參見正則表示式學習,一個左括號“(”,表示一個分組),就可以在match物件上用group()方法提取出子串來。後面會單獨寫一下group()和groups()的用法,這裡先簡單瞭解一下。
re.match與re.search的區別:
re.match只匹配字串的開始,如果字串開始不符合正則表示式,則匹配失敗,函式返回None;而re.search匹配整個字串,直到找到一個匹配(注意:僅僅是第一個)
3. re.findall()
在字串中找到正則表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表
注意: match 和 search 是匹配一次,而findall 匹配所有
>>> re.findall(r'\d{2}','21c34d56e78')
['21', '34', '56', '78']
4. re.finditer()
和 findall 類似,在字串中找到正則表示式所匹配的所有子串,並把它們作為一個迭代器返回.
示例:
>>> match = re.finditer(r'\d{2}','21c34d56e78')
>>> for t in match:
print(t.group())
21
34
56
78
>>>
5. re.split()
根據正則表示式中的分隔符把字元分割為一個列表並返回成功匹配的列表.
示例:
>>> match = re.split(r'\.|-','hello-world.data') # 使用 . 或 - 作為字串的分隔符
>>> print(match)
['hello', 'world', 'data']
字串也有split方法,如下,作個對比:
字串的split方法
>>> 'a b c'.split(' ') # b和c之間有3個空格
['a', 'b', '', '', 'c']
如果用空格不好理解的話,可以換位x
>>> 'axbxxxc'.split('x')
['a', 'b', '', '', 'c']
>>>
可以看到,單純用字串的split方法無法識別連續的空格,
用正則表示式如下:
>>> re.split(r'\s+', 'a b c') # \s+ 表示匹配一個或多個空白符(\s表示匹配空白符,+表示重複1次或1次以上)
['a', 'b', 'c']
>>>
6. re.sub()
用於替換字串中的匹配項
語法: re.sub(pattern, repl, string, count=0)
pattern:正則中的模式字串。
repl:替換的字串,也可為一個函式。
string:要被查詢替換的原始字串。
count:模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。
示例:
>>> match = re.sub(r'a', 'b','aaccaa') # 把字串中的a都替換為b
>>> print(match)
bbccbb
>>>
7. re.compile()
compile 函式用於編譯正則表示式,生成一個正則表示式( Pattern )物件,然後就可以用編譯後的正則表示式去匹配字串
語法如下:
>>> help(re.compile)
Help on function compile in module re:
compile(pattern, flags=0)
Compile a regular expression pattern, returning a pattern object.
>>>
pattern : 一個字串形式的正則表示式
flags :可選,表示匹配模式,比如忽略大小寫,多行模式等
示例:
>>> test_pattern = re.compile(r'\d{2}') # 編譯一個正則表示式,並將其賦給一個變數 >>> m = test_pattern.match('12bc34') # 使用編譯後的正則表示式物件直接匹配字串 >>> m <_sre.SRE_Match object; span=(0, 2), match='12'> >>> test_pattern = re.compile(r'a\w+') # 生成一個正則表示式物件(這裡是匹配以a開頭的單詞) >>> m = test_pattern.findall('apple,blue,alone,shot,attack') # 使用findall()函式匹配所有滿足匹配規則的子串 >>> m ['apple', 'alone', 'attack']
8. group()和groups()
一般用match()或search()函式匹配,得到匹配物件後,需要用group()方法獲得匹配內容;同時也可以提取分組截獲的字串(正則表示式中()用來分組)
示例:
>>> pattern = re.compile(r'^(\d{3})-(\d{3,8})$') # 匹配一個3位數開頭,然後一個-,然後跟著3-8位數字的字串 >>> m = pattern.match('020-1234567') >>> m <_sre.SRE_Match object; span=(0, 11), match='020-1234567'> >>> m.group() # 顯示整個匹配到的字元 '020-1234567' >>> m.group(0) # 同樣是顯示整個匹配到的字元 '020-1234567' >>> m.group(1) # 提取第1個分組中的子串 '020' >>> m.group(2) # 提取第2個分組中的子串 '1234567' >>> m.group(3) # 因為不存在第3個分組,所以這裡會報錯:沒有這樣的分組 Traceback (most recent call last): File "<pyshell#73>", line 1, in <module> m.group(3) IndexError: no such group >>> m.groups() ('020', '1234567') >>>