一、正則表達式
1.正則表達式概述
正則表達式,又稱規則表達式。(英語:Regular Expression,在代碼中常簡寫為regex、regexp或RE),計算機科學的一個概念。正則表達式通常被用來檢索、替換那些符合某個模式(規則)的文本。正則表達式(Regular Expression)是一種文本模式,包括普通字符(例如,a 到 z 之間的字母)和特殊字符(稱為"元字符")。正則表達式使用單個字符串來描述、匹配一系列匹配某個句法規則的字符串。正則表達式是煩瑣的,但它是強大的,學會之后的應用會讓你除了提高效率外,會給你帶來絕對的成就感。
2.表達式列表
表達式 | 說明 | |
字符匹配 | [0-9] | 匹配0-9之間的任意1個數字。 |
[a-z] | 表示某個范圍內的字符。與指定區間內的任何字符匹配。例如,"[a-z]"匹配"a"與"z"之間的任何1個小寫字母。 |
|
[A-Z] | 表示某個范圍內的字符。與指定區間內的任何字符匹配。例如,"[A-Z]"匹配"A"與"Z"之間的任何1個大寫字母。 | |
元字符匹配 | . |
匹配換行符以外的任何字符。 |
\w |
與任何單詞字符匹配,包括下划線。等價於"[A-Za-z0-9_]"。 | |
\s |
與任何白字符匹配,包括空格、制表符、分頁符等。等價於"[\f\n\r\t\v]"。 | |
\d |
與一個數字字符匹配。等價於[0-9]。 | |
\n |
與換行符字符匹配。 | |
\t |
與制表符匹配。 | |
\b |
與單詞的邊界匹配,即單詞與空格之間的位置。例如,"er\b"與"never"中的"er"匹配,但是不匹配"verb"中的"er"。 | |
^ |
匹配輸入的開始位置。 | |
$ |
匹配輸入的結尾。 | |
\W |
與任何非單詞字符匹配。等價於"[^A-Za-z0-9_]"。 | |
\D |
與非數字的字符匹配。等價於[^0-9]。 | |
\S |
與任何非空白的字符匹配。等價於"[^\f\n\r\t\v]"。 | |
x|y |
匹配x或y。例如"z|food"可匹配"z"或"food"。"(z|f)ood"匹配"zood"或"food"。 | |
() |
群組,與模式匹配並記住匹配。匹配的子字符串可以從作為結果的Matches集合中使用Item[0]... [n]取得。如果要匹配括號字符(和),可使用"\("或"\)"。 | |
[xyz] |
一個字符集。與括號中字符的其中之一匹配。例如,"[abc]"匹配"plain"中的"a"。 | |
[^xyz] |
一個否定的字符集。匹配不在此括號中的任何字符。例如,"[^abc]"可以匹配"plain"中的"pl". | |
量詞 | * |
匹配前一個字符零次或幾次。例如,"zo*"可以匹配"z"、"zoo"。 |
+ |
匹配前一個字符一次或多次。例如,"zo+"可以匹配"zoo",但不匹配"z"。 | |
? |
匹配前一個字符零次或一次。例如,"a?ve?"可以匹配"never"中的"ve"。 | |
{n} |
n為非負的整數。匹配恰好n次。例如,"o{2}"不能與"Bob中的"o"匹配,但是可以與"foooood"中的前兩個o匹配。 | |
{n,} |
n為非負的整數。匹配至少n次。例如,"o{2,}"不匹配"Bob"中的"o",但是匹配"foooood"中所有的o。"o{1,}"等價於"o+"。"o{0,}"等價於"o*"。 | |
{n,m} |
m和n為非負的整數。匹配至少n次,至多m次。例如,"o{1,3}"匹配"fooooood"中前三個o。"o{0,1}"等價於"o?"。 |
3.表達式的應用區別
(1).^${}的區別
正則 | 待匹配字符 | 匹配 結果 |
說明 |
李.? | 李傑和李蓮英和李二棍子 | 李傑 |
?表示重復零次或一次,即只匹配"李"后面一個任意字符 |
李.* | 李傑和李蓮英和李二棍子 | 李傑和李蓮英和李二棍子 | *表示重復零次或多次,即匹配"李"后面0或多個任意字符 |
李.+ | 李傑和李蓮英和李二棍子 | 李傑和李蓮英和李二棍子 | +表示重復一次或多次,即只匹配"李"后面1個或多個任意字符 |
李.{1,2} | 李傑和李蓮英和李二棍子 | 李傑和 |
{1,2}匹配1到2次任意字符 |
注意:前面的*,+,?等都是貪婪匹配,也就是盡可能匹配,在一個量詞后面加?號使其變成惰性匹配
正則 | 待匹配字符 | 匹配 結果 |
說明 |
李.*? | 李傑和李蓮英和李二棍子 | 李 李 李 |
惰性匹配 |
(2)字符集[ ] [ ^ ]
正則 | 待匹配字符 | 匹配 結果 |
說明 |
李[傑蓮英二棍子]* | 李傑和李蓮英和李二棍子 | 李傑 |
表示匹配"李"字后面[傑蓮英二棍子]的字符任意次 |
李[^和]* | 李傑和李蓮英和李二棍子 | 李傑 |
表示匹配一個不是"和"的字符任意次 |
[\d] | 456bdha3 | 4 |
表示匹配任意一個數字,匹配到4個結果 |
[\d]+ | 456bdha3 | 456 |
表示匹配任意個數字,匹配到2個結果 |
(3)轉移符\
在正則表達式中,有很多有特殊意義的是元字符,比如\d和\s等,如果要在正則中匹配正常的"\d"而不是"數字"就需要對"\"進行轉義,變成'\\'。
在python中,無論是正則表達式,還是待匹配的內容,都是以字符串的形式出現的,在字符串中\也有特殊的含義,本身還需要轉義。所以如果匹配一次"\d",字符串中要寫成'\\d',那么正則里就要寫成"\\\\d",這樣就太麻煩了。這個時候我們就用到了r'\d'這個概念,此時的正則是r'\\d'就可以了。
正則 | 待匹配字符 | 匹配 結果 |
說明 |
\d | \d | False | 因為在正則表達式中\是有特殊意義的字符,所以要匹配\d本身,用表達式\d無法匹配 |
\\d | \d | True | 轉義\之后變成\\,即可匹配 |
"\\\\d" | '\\d' | True | 如果在python中,字符串中的'\'也需要轉義,所以每一個字符串'\'又需要轉義一次 |
r'\\d' | r'\d' | True | 在字符串之前加r,讓整個字符串不轉義 |
(4)貪婪匹配
貪婪匹配:在滿足匹配時,匹配盡可能長的字符串,默認情況下,采用貪婪匹配。
正則 | 待匹配字符 | 匹配 結果 |
說明 |
<.*> | <script>...<script> |
<script>...<script> | 默認為貪婪匹配模式,會匹配盡量長的字符串 |
<.*?> | r'\d' | <script> |
加上?為將貪婪匹配模式轉為非貪婪匹配模式,會匹配盡量短的字符串 |
幾個常用的非貪婪匹配模式
*? 重復任意次,但盡可能少重復 +? 重復1次或更多次,但盡可能少重復 ?? 重復0次或1次,但盡可能少重復 {n,m}? 重復n到m次,但盡可能少重復 {n,}? 重復n次以上,但盡可能少重復
.*?的用法
. 是任意字符 * 是取 0 至 無限長度 ? 是非貪婪模式。 何在一起就是 取盡量少的任意字符,一般不會這么單獨寫,他大多用在: .*?x 就是取前面任意長度的字符,直到一個x出現
二、RE模塊
1.re函數方法總結
方法名稱 | 格式 | 說明 |
findall | re.findall(表達式,字符串) | 返回所有滿足匹配條件的結果,放在列表里 |
search | re.search(表達式,字符串).groups() | 函數會在字符串內查找模式匹配,只到找到第一個匹配然后返回一個包含匹配信息的對象,該對象可以 通過調用group()方法得到匹配的字符串,如果字符串沒有匹配,則返回None。 |
match | re.match(表達式,字符串).groups() | 同search,不過盡在字符串開始處進行匹配 |
split | re.split(表達式,字符串) | 按表達式對字符串分割,返回列表 |
sub | re.sub(表達式,替換字符,字符串,count) | 按表達式類型替換成新的字符,返回字符串 |
subn | re.subn(表達式,替換字符,字符串,count) | 按表達式類型替換成新的字符串,返回一個元組,存放這替換結果和替換次數 |
compile | re.compile(表達式) | 將正則表達式編譯成為一個 正則表達式對象 |
finditer | re.finditer(表達式,字符串) | finditer返回一個存放匹配結果的迭代器 |
2.常用方法實例
#(1)findall
import re ret = re.findall('\d','adsf123456we7we') #匹配字符串中是數字的字符,並將匹配值返回到列表中
print(ret) '''結果: ['1', '2', '3', '4', '5', '6', '7'] '''
#(2)search
ret = re.search('\d','adsf123456we7we').group() #按照表達式匹配到第一個值就返回
print(ret) '''結果: 1 '''
#(3)match
ret = re.match('\w','adsf123456we7we').group() #按照表達式匹配開頭第一個值,符合的話就返回,不符合就報錯
print(ret) '''結果: a '''
#(4)sub
ret = re.sub('\d','*','adsf123456we7we',0) #匹配字符串中的數字,並且替換成*號,0表示替換所有
print(ret) '''結果: adsf******we*we '''
#(5)subn
ret = re.subn('\d','*','adsf123456we7we',0) #匹配字符串中的數字,並且替換成*號,返回一個元組,存放這替換結果和替換次數
print(ret) '''結果: ('adsf******we*we', 7) '''
#(6)compile
obj = re.compile('\d') #將正則表達式編譯成一個正則表達式對象
ret = obj.search('ads123asd456').group() print(ret) '''結果: 1 '''
#(7)finditer
ret = re.finditer('\d','adsf451we15615adf16') #finditer返回一個存放匹配結果的迭代器
print(ret) for i in ret: print(i.group())