在本教程中,您將學(xué)習(xí)正則表達(dá)式(RegEx),并使用Python的re模塊與RegEx一起使用(在示例的幫助下)。
正則表達(dá)式(RegEx)是定義搜索模式的字符序列。 例如,
^a...s$
上面的代碼定義了RegEx模式。模式是:以a開頭并以s結(jié)尾的任何五個字母字符串。
使用RegEx定義的模式可用于與字符串匹配。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
^a...s$ | abs | 沒有匹配 |
alias | 匹配 | |
abyss | 匹配 | |
Alias | 沒有匹配 | |
An abacus | 沒有匹配 |
Python有一個名為reRegEx 的模塊。這是一個示例:
import re pattern = '^a...s$' test_string = 'abyss' result = re.match(pattern, test_string) if result: print("查找成功.") else: print("查找不成功.")
這里,我們使用re.match()函數(shù)來搜索測試字符串中的模式。如果搜索成功,該方法將返回一個匹配對象。如果沒有,則返回None。
re模塊中定義了其他一些函數(shù),可與RegEx一起使用。在探討之前,讓我們學(xué)習(xí)正則表達(dá)式本身。
如果您已經(jīng)了解RegEx的基礎(chǔ)知識,請?zhí)?a href="#python-regex">Python RegEx。
為了指定正則表達(dá)式,使用了元字符。在上面的示例中,^和$是元字符。
元字符是RegEx引擎以特殊方式解釋的字符。以下是元字符列表:
[] . ^ $ * + ? {} () \ |
[] - 方括號
方括號指定您要匹配的一組字符。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
[abc] | a | 1個匹配 |
ac | 2個匹配 | |
Hey Jude | 沒有匹配 | |
abc de ca | 5個匹配 |
在這里,[abc]將匹配,如果你想匹配字符串中包含任何的a,b或c。
您也可以使用-方括號內(nèi)的字符范圍。
[a-e]與相同[abcde]。
[1-4]與相同[1234]。
[0-39]與相同[01239]。
您可以通過^在方括號的開頭使用插入符號來補(bǔ)充(反轉(zhuǎn))字符集。
[^abc]表示除a或b或c之外的任何字符。
[^0-9] 表示任何非數(shù)字字符。
.- 句點
句點匹配任何單個字符(換行符除外'\n')。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
.. | a | 沒有匹配 |
ac | 1個匹配 | |
acd | 1個匹配 | |
acde | 2個匹配項(包含4個字符) |
^- 插入符號
插入符號^用于檢查字符串是否以某個字符開頭。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
^a | a | 1個匹配 |
abc | 1個匹配 | |
bac | 沒有匹配 | |
^ab | abc | 1個匹配 |
acb | 沒有匹配項(以開頭,a但之后沒有b) |
$- 美元
美元符號$用于檢查字符串是否以某個特定字符結(jié)尾。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
a$ | a | 1個匹配 |
formula | 1個匹配 | |
cab | 沒有匹配 |
*- 星號
星號符號*匹配零個或多個剩余的模式。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
ma*n | mn | 1個匹配 |
man | 1個匹配 | |
maaan | 1個匹配 | |
main | 沒有匹配項(a后面沒有n) | |
woman | 1個匹配 |
+- 加號
加號會+匹配一個或多個剩余的模式。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
ma+n | mn | 沒有匹配項(沒有a字符) |
man | 1個匹配 | |
maaan | 1個匹配 | |
main | 沒有匹配項(a后跟n) | |
woman | 1個匹配 |
?- 問號
問號符號會?匹配零或一出現(xiàn)的剩余模式。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
ma?n | mn | 1個匹配 |
man | 1個匹配 | |
maaan | 沒有匹配項(超過一個a字符) | |
main | 沒有匹配項(a后跟n) | |
woman | 1個匹配 |
{}- 大括號
考慮以下代碼:{n,m}。這意味著至少要保留n個樣式,并且最多重復(fù)m個樣式。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
a{2,3} | abc dat | 沒有匹配 |
abc daat | 1個匹配(在)daat | |
aabc daaat | 2個匹配項(位于aabc和)daaat | |
aabc daaaat | 2個匹配項(位于aabc和)daaaat |
讓我們再嘗試一個示例。RegEx [0-9]{2, 4}匹配至少2位但不超過4位
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
[0-9]{2,4} | ab123csde | 1個匹配(在處匹配)ab123csde |
12 and 345673 | 2個匹配項(位于)12 and 345673 | |
1 and 2 | 沒有匹配 |
|- 豎線
豎線|用于交替顯示(or運算符)。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
a|b | cde | 沒有匹配 |
ade | 1個匹配(在處匹配ade) | |
acdbea | 3個匹配項(位于)acdbea |
在這里,a|b匹配任何包含a或b的字符串
()- 括號
括號()用于對子模式進(jìn)行分組。例如,(a|b|c)xz匹配任何與a或b或c匹配且后跟xz的字符串
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
(a|b|c)xz | ab xz | 沒有匹配 |
abxz | 1個匹配(在處匹配)abxz | |
axz cabxz | 2個匹配項(位于)axzbc cabxz |
\- 反斜杠
反斜杠\用于轉(zhuǎn)義包括所有元字符在內(nèi)的各種字符。例如,
\$a如果字符串包含$后跟則匹配a。在此,$RegEx引擎不會以特殊方式對其進(jìn)行解釋。
如果不確定某個字符是否具有特殊含義,可以將其\放在前面。這樣可以確保不對字符進(jìn)行特殊處理。
特殊序列
特殊序列使常用模式更易于編寫。以下是特殊序列的列表:
\A -如果指定字符在字符串的開頭,則匹配。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\Athe | the sun | 匹配 |
In the sun | 沒有匹配 |
\b -如果指定的字符在單詞的開頭或結(jié)尾,則匹配。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\bfoo | football | 匹配 |
a football | 匹配 | |
afootball | 沒有匹配 | |
foo\b | the foo | 匹配 |
the afoo test | 匹配 | |
the afootest | 沒有匹配 |
\B-與\b。如果指定的字符不在單詞的開頭或結(jié)尾,則匹配。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\Bfoo | football | 沒有匹配 |
a football | 沒有匹配 | |
afootball | 匹配 | |
foo\B | the foo | 沒有匹配 |
the afoo test | 沒有匹配 | |
the afootest | 匹配 |
\d-匹配任何十進(jìn)制數(shù)字。相當(dāng)于[0-9]
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\d | 12abc3 | 3個匹配項(位于)12abc3 |
Python | 沒有匹配 |
\D-匹配任何非十進(jìn)制數(shù)字。相當(dāng)于[^0-9]
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\D | 1ab34"50 | 3個匹配項(位于)1ab34"50 |
1345 | 沒有匹配 |
\s-匹配字符串包含任何空格字符的地方。等同于[ \t\n\r\f\v]。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\s | Python RegEx | 1個匹配 |
PythonRegEx | 沒有匹配 |
\S-匹配字符串包含任何非空白字符的地方。等同于[^ \t\n\r\f\v]。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\S | a b | 2個匹配項(位于) a b |
沒有匹配 |
\w-匹配任何字母數(shù)字字符(數(shù)字和字母)。等同于[a-zA-Z0-9_]。順便說一下,下劃線_也被認(rèn)為是字母數(shù)字字符。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\w | 12&": ;c | 3個匹配項(位于)12&": ;c |
%"> ! | 沒有匹配 |
\W-匹配任何非字母數(shù)字字符。相當(dāng)于[^a-zA-Z0-9_]
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\W | 1a2%c | 1個匹配(在)1a2%c |
Python | 沒有匹配 |
\Z -如果指定的字符在字符串的末尾,則匹配。
表達(dá)式 | 字符串 | 匹配? |
---|---|---|
\ZPython | I like Python | 1個匹配 |
I like Python | 沒有匹配 | |
Python is fun. | 沒有匹配 |
提示:要構(gòu)建和測試正則表達(dá)式,可以使用RegEx測試器工具,例如regex。該工具不僅可以幫助您創(chuàng)建正則表達(dá)式,還可以幫助您學(xué)習(xí)它。
現(xiàn)在,您了解了RegEx的基礎(chǔ)知識,讓我們討論如何在Python代碼中使用RegEx。
Python有一個名為re正則表達(dá)式的模塊。要使用它,我們需要導(dǎo)入模塊。
import re
該模塊定義了一些可與RegEx一起使用的函數(shù)和常量。
re.findall()方法返回包含所有匹配項的字符串列表。
# 從字符串中提取數(shù)字的程序 import re string = 'hello 12 hi 89. Howdy 34' pattern = '\d+' result = re.findall(pattern, string) print(result) # 輸出: ['12', '89', '34']
如果找不到該模式,則re.findall()返回一個空列表。
split方法對匹配的字符串進(jìn)行拆分,并返回發(fā)生拆分的字符串列表。
import re string = 'Twelve:12 Eighty nine:89.' pattern = '\d+' result = re.split(pattern, string) print(result) # 輸出: ['Twelve:', ' Eighty nine:', '.']
如果找不到該模式,則re.split()返回一個包含空字符串的列表。
您可以將maxsplit參數(shù)傳遞給re.split()方法。這是將要發(fā)生的最大拆分次數(shù)。
import re string = 'Twelve:12 Eighty nine:89 Nine:9.' pattern = '\d+' # maxsplit = 1 # split only at the first occurrence result = re.split(pattern, string, 1) print(result) # 輸出: ['Twelve:', ' Eighty nine:89 Nine:9.']
順便說一下,maxsplit默認(rèn)值為0;默認(rèn)值為0。意味著拆分所有匹配的結(jié)果。
re.sub()的語法:
re.sub(pattern, replace, string)
該方法返回一個字符串,其中匹配的匹配項被替換為replace變量的內(nèi)容。
# 刪除所有空格的程序 import re # 多行字符串 string = 'abc 12\ de 23 \n f45 6' # 匹配所有空白字符 pattern = '\s+' # 空字符串 replace = '' new_string = re.sub(pattern, replace, string) print(new_string) # 輸出: abc12de23f456
如果找不到該模式,則re.sub()返回原始字符串。
您可以將count作為第四個參數(shù)傳遞給該re.sub()方法。如果省略,則結(jié)果為0。這將替換所有出現(xiàn)的匹配項。
import re # 多行字符串 string = 'abc 12\ de 23 \n f45 6' # 匹配所有空白字符 pattern = '\s+' replace = '' new_string = re.sub(r'\s+', replace, string, 1) print(new_string) # 輸出: # abc12de 23 # f45 6
re.subn()與re.sub()類似,期望它返回一個包含2個項目的元組,其中包含新字符串和進(jìn)行替換的次數(shù)。
# 刪除所有空格的程序 import re # 多行字符串 string = 'abc 12\ de 23 \n f45 6' # 匹配所有空白字符 pattern = '\s+' # 空字符串 replace = '' new_string = re.subn(pattern, replace, string) print(new_string) # 輸出: ('abc12de23f456', 4)
re.search()方法采用兩個參數(shù):模式和字符串。 該方法尋找RegEx模式與字符串匹配的第一個位置。
如果搜索成功,則re.search()返回一個匹配對象。如果不是,則返回None。
match = re.search(pattern, str)
import re string = "Python is fun" # 檢查“Python”是否在開頭 match = re.search('\APython', string) if match: print("pattern found inside the string") else: print("pattern not found") # 輸出: pattern found inside the string
在這里,match包含一個match對象。
您可以使用dir()函數(shù)獲取匹配對象的方法和屬性。
匹配對象的一些常用方法和屬性是:
group()方法返回字符串中匹配的部分。
import re string = '39801 356, 2102 1111' # 三位數(shù)字,后跟空格,后兩位數(shù)字 pattern = '(\d{3}) (\d{2})' # match變量包含一個Match對象。 match = re.search(pattern, string) if match: print(match.group()) else: print("pattern not found") # 輸出: 801 35
在這里,match變量包含一個match對象。
我們的模式(\d{3}) (\d{2})有兩個子組(\d{3})和(\d{2})。您可以獲取這些帶括號的子組的字符串的一部分。就是這樣:
>>> match.group(1) '801' >>> match.group(2) '35' >>> match.group(1, 2) ('801', '35') >>> match.groups() ('801', '35')
start()函數(shù)返回匹配的子字符串的開頭的索引。同樣,end()返回匹配的子字符串的結(jié)束索引。
>>> match.start() 2 >>> match.end() 8
span()函數(shù)返回一個包含匹配部分的開始和結(jié)束索引的元組。
>>> match.span() (2, 8)
匹配對象的re屬性返回一個正則表達(dá)式對象。 同樣,string屬性返回傳遞的字符串。
>>> match.re re.compile('(\\d{3}) (\\d{2})') >>> match.string '39801 356, 2102 1111'
我們已經(jīng)介紹了re模塊中定義的所有常用方法。如果您想了解更多信息,請訪問Python 3 re模塊。
如果在正則表達(dá)式之前使用r或R前綴,則表示原始字符串。例如,'\n'是一個新行,而r'\n'表示兩個字符:反斜杠\后跟n。
反斜杠\用于轉(zhuǎn)義包括所有元字符在內(nèi)的各種字符。但是,使用r前綴\會將其視為普通字符。
import re string = '\n and \r are escape sequences.' result = re.findall(r'[\n\r]', string) print(result) # 輸出: ['\n', '\r']