正則表達式(RegularExpression,re)
- 匹配符合某個規(guī)則的字符串
- 常用于檢索魔眨,替換某些模式的文本
正則的寫法
- \d:任意一個數(shù)字殉簸,等價于 [0-9]
- \D:匹配任意非數(shù)字
- \s:匹配任意空白字符,等價于 [\t\n\r\f]
- \S:匹配任意非空字符
- \w:字母票摇、數(shù)字、下劃線,a-z左腔,A-Z,0-9捅儒,_
- \W:除了字母液样、數(shù)字、下劃線巧还,a-z鞭莽,A-Z,0-9麸祷,_
- \A:匹配字符串開始
- \z:匹配字符串結(jié)束
- \Z:匹配字符串結(jié)束澎怒,如果是存在換行,只匹配到換行前的結(jié)束字符
- ^:匹配字符串的開始
- $:匹配字符串的結(jié)尾
- .(點號):表示任意一個字符阶牍,除了\n喷面,比如查找所有的一個字符 \.
- [...]:匹配中括號中列舉的任意字符,[amk] 匹配 'a'荸恕,'m'或'k'
- [^...]:不在[ ]中的字符乖酬,[^abc] 匹配除了a,b,c之外的字符
- *:表示前面的內(nèi)容重復(fù)零次或多次
- +:前面的內(nèi)容至少出現(xiàn)一次
- ?:前面的內(nèi)容出現(xiàn)一次或零次
- {m,n}:前面的內(nèi)容出現(xiàn)最最少m次融求,最多n次
- a| b:匹配a或b
- (re):對正則表達式分組并記住匹配的文本
示例:
- 驗證一個數(shù)字:^\d$
- 至少一個數(shù)字:^\d+$
- 5-10位數(shù)字:^\d{5-10}$
- 16以上咬像,99以下:^[16-99]$
- 英文字符和數(shù)字:^[A-Za-z0-9]$
使用步驟:
- 使用compile將表示正則的字符串編譯為一個pattern對象
- 通過pattern對象提供的一系列方法對文本進行查找匹配,該對象擁有一系列方法用于正則表達式匹配和替換生宛,獲得匹配結(jié)果县昂,一個Match對象
- 最后使用Match對象提供的屬性和方法獲得信息,根據(jù)需要進行操作
貪婪和非貪婪
- 貪婪:盡可能多的匹配陷舅,(*)表示貪婪匹配
- 非貪婪:找到符合條件的最小內(nèi)容即可倒彰,(?)表示非貪婪
re.match函數(shù)
re.match 嘗試從字符串的起始位置匹配一個模式,匹配成功re.match方法返回一個匹配的對象莱睁,否則返回None待讳。如果不是起始位置匹配成功的話芒澜,match()返回none。
函數(shù)語法:
re.match(pattern,string,flags=0)
函數(shù)參數(shù)說明:
參數(shù) | 描述 |
---|---|
pattern | 匹配的正則表達式 |
string | 要匹配的字符串 |
flags | 標志位创淡,用于控制正則表達式的匹配方式痴晦,如:是否區(qū)分大小寫,多行匹配等等琳彩。 |
正則表達式可以包含一些可選標志修飾符來控制匹配的模式誊酌。修飾符被指定為一個可選的標志。多個標志可以通過按位 OR(|) 它們來指定露乏。如 re.I | re.M 被設(shè)置成 I 和 M 標志:
修飾符 | 描述 |
---|---|
re.I | 使匹配對大小寫不敏感 |
re.M | 多行匹配碧浊,影響 ^ 和 $ |
re.S | 使 . 匹配包括換行在內(nèi)的所有字符 |
re.U | 根據(jù)Unicode字符集解析字符。這個標志影響 \w, \W, \b, \B. |
可以使用group(num) 或 groups() 匹配對象函數(shù)來獲取匹配表達式瘟仿。
匹配對象方法 | 描述 |
---|---|
group(num=0) | 匹配的整個表達式的字符串箱锐,group() 可以一次輸入多個組號,在這種情況下它將返回一個包含那些組所對應(yīng)值的元組猾骡。 |
groups() | 返回一個包含所有小組字符串的元組瑞躺,從 1 到 所含的小組號敷搪。 |
代碼示例:
# 導(dǎo)入相關(guān)包
import re
print(re.match('www', 'www.runoob.com')) # 在起始位置匹配
print(re.match('www', 'www.runoob.com').span())
print(re.match('com', 'www.runoob.com')) # 不在起始位置匹配
line = "Cats are smarter than dogs"
# r表示字符串不轉(zhuǎn)義
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
print('matchObj.group():',matchObj.group())
print('matchObj.group():',matchObj.groups())
print('matchObj.group(1):',matchObj.group(1))
print('matchObj.group(2):',matchObj.group(2))
else:
print('No match!!')
運行結(jié)果為:
<re.Match object; span=(0, 3), match='www'>
(0, 3)
None
matchObj.group(): Cats are smarter than dogs
matchObj.group(): ('Cats', 'smarter')
matchObj.group(1): Cats
matchObj.group(2): smarter
re.search函數(shù)
re.search 掃描整個字符串并返回第一個成功的匹配兴想。
函數(shù)語法:
re.search(pattern, string, flags=0)
代碼示例:
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!!")
運行結(jié)果為:
searchObj.group() : Cats are smarter than dogs
searchObj.group(1) : Cats
searchObj.group(2) : smarter
re.match與re.search的區(qū)別
re.match只匹配字符串的開始,如果字符串開始不符合正則表達式赡勘,則匹配失敗嫂便,函數(shù)返回None;而re.search匹配整個字符串闸与,直到找到一個匹配毙替。
代碼示例:
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 --> searchObj.group() : ", matchObj.group())
else:
print("No match!!")
運行結(jié)果為:
No match!!
search --> searchObj.group() : dogs
檢索和替換
Python 的 re 模塊提供了re.sub用于替換字符串中的匹配項。
函數(shù)語法
re.sub(pattern, repl, string, count=0, flags=0)
函數(shù)參數(shù)說明:
參數(shù) | 描述 |
---|---|
pattern | 正則中的模式字符串 |
repl | 替換的字符串践樱,也可為一個函數(shù) |
string | 要被查找替換的原始字符串 |
count | 模式匹配后替換的最大次數(shù)厂画,默認 0 表示替換所有的匹配 |
代碼示例
import re
phone = "2004-959-559 # 這是一個國外電話號碼"
# 刪除字符串中的 Python注釋
num = re.sub(r'#.*$', "", phone)
print("電話號碼是: ", num)
# 刪除非數(shù)字(-)的字符串
num = re.sub(r'\D', "", phone)
print("電話號碼是 : ", num)
運行結(jié)果為:
電話號碼是: 2004-959-559
電話號碼是 : 2004959559
repl 參數(shù)是一個函數(shù)
import re
# 將匹配的數(shù)字乘以 2
def double(matched):
value = int(matched.group('value'))
return str(value * 2)
s = 'A23G4HFD567'
print(re.sub('(?P<value>\d+)', double, s))
運行結(jié)果為:
A46G8HFD1134
re.compile函數(shù)
compile 函數(shù)用于編譯正則表達式,生成一個正則表達式( Pattern )對象拷邢,供 match() 和 search() 這兩個函數(shù)使用袱院。
語法格式
re.compile(pattern[, flags])
參數(shù):
- pattern : 一個字符串形式的正則表達式
- flags : 可選,表示匹配模式瞭稼,比如忽略大小寫忽洛,多行模式等,具體參數(shù)為:
- re.I 忽略大小寫
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴于當(dāng)前環(huán)境
- re.M 多行模式
- re.S 即為 . 并且包括換行符在內(nèi)的任意字符(. 不包括換行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴于 Unicode 字符屬性數(shù)據(jù)庫
- re.X 為了增加可讀性环肘,忽略空格和 # 后面的注釋
代碼示例:
>>>import re
>>> pattern = re.compile(r'\d+') # 用于匹配至少一個數(shù)字
>>> 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)
在上面复哆,當(dāng)匹配成功時返回一個 Match 對象欣喧,其中:
- group([group1, …]) ,方法用于獲得一個或多個分組匹配的字符串梯找,當(dāng)要獲得整個匹配的子串時续誉,可直接使用 group() 或 group(0);
- start([group]) 初肉,方法用于獲取分組匹配的子串在整個字符串中的起始位置(子串第一個字符的索引)酷鸦,參數(shù)默認值為 0;
- end([group]) 方法用于獲取分組匹配的子串在整個字符串中的結(jié)束位置(子串最后一個字符的索引+1)牙咏,參數(shù)默認值為 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
findall
在字符串中找到正則表達式所匹配的所有子串妄壶,并返回一個列表摔握,如果沒有找到匹配的,則返回空列表丁寄。
注意: match 和 search 是匹配一次氨淌,findall 匹配所有
語法格式
findall(string[, pos[, endpos]])
參數(shù):
- string : 待匹配的字符串。
- pos : 可選參數(shù)伊磺,指定字符串的起始位置盛正,默認為 0。
- endpos : 可選參數(shù)屑埋,指定字符串的結(jié)束位置豪筝,默認為字符串的長度。
代碼示例:
import re
pattern = re.compile(r'\d+') # 查找數(shù)字
result1 = pattern.findall('runoob 123 google 456')
result2 = pattern.findall('run88oob123google456', 0, 10)
print(result1)
print(result2)
輸出結(jié)果:
['123', '456']
['88', '12']
re.finditer
和 findall 類似摘能,在字符串中找到正則表達式所匹配的所有子串续崖,并把它們作為一個迭代器返回。
語法格式:
re.finditer(pattern, string, flags=0)
代碼示例:
import re
it = re.finditer(r"\d+","12a32bc43jf3")
for match in it:
print (match.group() )
輸出結(jié)果:
12
32
43
3
re.split函數(shù)
split 方法按照能夠匹配的子串將字符串分割后返回列表团搞,它的使用形式如下:
語法格式:
re.split(pattern, string[, maxsplit=0, flags=0])
參數(shù):
參數(shù) | 描述 |
---|---|
pattern | 匹配的正則表達式 |
string | 要匹配的字符串严望。 |
maxsplit | 分隔次數(shù),maxsplit=1 分隔一次逻恐,默認為 0像吻,不限制次數(shù)。 |
flags | 標志位梢莽,用于控制正則表達式的匹配方式萧豆,如:是否區(qū)分大小寫,多行匹配等等昏名。 |
代碼示例:
>>>import re
>>> re.split('\W+', 'runoob, runoob, runoob.')
['runoob', 'runoob', 'runoob', '']
>>> re.split('(\W+)', ' runoob, runoob, runoob.')
['', ' ', 'runoob', ', ', 'runoob', ', ', 'runoob', '.', '']
>>> re.split('\W+', ' runoob, runoob, runoob.', 1)
['', 'runoob, runoob, runoob.']
>>> re.split('a*', 'hello world') # 對于一個找不到匹配的字符串而言涮雷,split 不會對其作出分割
['hello world']