目錄
閱讀本文章時,已默認您對正則表達式有了一定的瞭解。該教程是對Python的re模塊的介紹及注意點提示,希望對您有一定的幫助,如果有解釋不到位的地方,還請各位朋友幫忙指出,大家一起進步。好了,那就讓我們開始Python正則之旅吧!
最好的學習資料是官方文檔,那我們先來看下Python文檔裏面的介紹,我的版本是Python3.7.2。
import re
help(re)
可以看到目前的Python版本re模塊裏面包含了以下幾個正則相關的方法:
現在我們就按這個順序來介紹下這幾個方法。
re.match
根據官方的介紹,我們可以知道該方法有三個參數 :
- pattern 表示傳進來的正則表達式
- string 表示被匹配的字符串
- flags 正則表達式匹配的模式
如下,目前支持7種模式:
對應的中文解釋
- A 該模式會讓正則表達式以ASCII字符集去匹配字符串,而不是以Unicode。主要影響的正則有
\w、\W、\d、\D、\b、\B
- I 忽略大小寫
- L 該模式會使以下正則根據本地環境去匹配
\w、\W、\b、\B
- M 多行模式匹配,影響^和$
- S 會使.元字符匹配所有字符,包括換行符
- X 忽略空白符和註釋,主要用於書寫正則的格式,添加註釋等,爲了更好的解釋所寫的正則
- U 根據Unicode字符集匹配字符串
接下來,我們就用代碼來驗證該方法:
該方法是從字符串的起始位置開始匹配字符串。如果匹配上,則會返回一個對象,否則返回None
來看兩個例子,你就明白了
demo1
import re
result=re.match(r"\d+","abc123")
print(result)
結果如下:
None
demo2
import re
result=re.match(r"\d+","123abc")
print(result)
<re.Match object; span=(0, 3), match='123'>
看到這裏,我想你應該明白re.match這個方法的用法了吧。後面我們會把該方法和re.search做比較。現在我們再來看看,返回的這個Match對象對應的類的一個介紹。
在這裏可以看到,re.match()和re.search()返回的結果都是Match這個類的一個實例 對象
下圖是該類的幾個比較常用的方法:
re.fullmatch
該方法需要整個字符串跟正則完全匹配纔會返回一個Match對象,否則返回None
demo1
import re
result=re.fullmatch(r"\d+","123abc")
print(result)
結果:
None
demo2
import re
result=re.fullmatch(r"\d+","123")
print(result)
<re.Match object; span=(0, 3), match='123'>
re.search
該方法會根據傳入的正則去掃描整個字符串,若能找到對應的子字符串,則返回該Match對象,否則返回None。這裏返回的Match對象保存的是從左到右匹配到的第一個子字符串的信息。
demo1
import re
result=re.search(r"\d+","abc123")
print(result)
<re.Match object; span=(3, 6), match='123'>
demo2
import re
result=re.search(r"\d+","abc1kkk")
print(result)
<re.Match object; span=(3, 4), match='1'>
demo3
import re
result=re.search(r"\d+","abckkk")
print(result)
None
可以看到,re.match和re.search都是在字符串中查找字符串,但區別是
- re.match 字符串的開始位置的字符串必須匹配該正則,否則返回None。你可以理解爲startWith的意思
- re.search 從左到右匹配,只要字符串中的任意一個子串能匹配到該正則,則返回匹配到的第一個子字符串的信息。你可以理解爲包含的意思
來看幾個等價的demo
import re
result=re.search(r"\A\d+","abc1kkk")
print(result)
result=re.match(r"\d+","abc1kkk")
print(result)
result=re.search(r"^\d+","abc1kkk")
print(result)
上面這幾個代碼的執行結果的一樣的,代碼所表示的含義也是一樣的。尋找的是開頭位置的數字
re.sub
這個方法的作用是字符串替換,其中,rep1可以是字符串,也可以是一個方法。
- 當rep1是一個字符串時,裏面的轉義字符會被加工處理。這裏怎麼理解呢?也就是說,是特殊符號的,會被轉爲對應的意思,rep1裏面的\n會被處理爲換行符,\r會被處理成回車換行符,不確定的轉義符不會處理,例如\&等。如果是向後引用的,則會替換成對應的引用組捕獲的內容,例如,\1會被替換成group(1)的內容,\2會被替換成group(2)的內容。
- 當rep1是一個方法時,該方法的入參是一個Match對象,並且必須有返回值
rep1爲字符串時的例子如下:
import re
#在每個匹配結果前後加上-
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k")
print(result)
#錯誤的寫法,rep1前面沒有加r
result=re.sub(r"(\d+)","-\1-","abc1kk2k")
print(result)
abc-1-kk-2-k
abc--kk--k
結果分析,從結果上面可以看到,當rep1字符串前面沒有加上r標識符的時候,裏面的\1會被按特殊字符處理爲它表示的意思,而加上r標識符之後,結果纔是正常的。當然,你可以像下面這麼寫:
import re
result=re.sub(r"(\d+)","-\g<1>-","abc1kk2k")
print(result)
result=re.sub(r"(\d+)",r"-\g<1>-","abc1kk2k")
print(result)
result=re.sub(r"\d+",r"-\g<0>-","abc1kk2k")
print(result)
result=re.sub(r"\d+","-\g<0>-","abc1kk2k")
print(result)
result=re.sub(r"(?P<num>\d+)",r"-\g<num>-","abc1kk2k")
print(result)
result=re.sub(r"(?P<num>\d+)","-\g<num>-","abc1kk2k")
print(result)
那如果我們需要把匹配到的每個數字加1,要怎麼寫呢?這個時候就需要在rep1傳入一個function方法了:
demo1
import re
def add(m):
return str(int(m.group())+1)
result=re.sub(r"\d+",add,"abc1kk2k")
print(result)
demo2
import re
result=re.sub(r"\d+",lambda m:str(int(m.group())+1),"abc1kk2k")
print(result)
demo3
import re
result=re.sub(r"(?P<num>\d+)",lambda m:str(int(m.group("num"))+1),"abc1kk2k")
print(result)
re.subn
該方法除了會多返回一個替換次數的結果外,其他功能都與sub一樣。返回結果是一個tupl
import re
result=re.subn(r"(\d+)",r"-\1-","abc1kk2k4")
print(result)
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k4")
print(result)
result=re.subn(r"(\d+)",r"-\1-","abc1kk2k4",2)
print(result)
result=re.sub(r"(\d+)",r"-\1-","abc1kk2k4",2)
print(result)
結果:
('abc-1-kk-2-k-4-', 3)
abc-1-kk-2-k-4-
('abc-1-kk-2-k4', 2)
abc-1-kk-2-k4
re.split
如果pattern沒有捕獲組的話,則按照正則分割後,返回一個list結果集;如果pattern裏面包含捕獲組的話,list結果集裏面包含捕獲組獲取到的內容
import re
result=re.split(r"\d+","abc11kk22k34")
print(result)
result=re.split(r"(\d+)","abc11kk22k34")
print(result)
result=re.split(r"\d+","abc11kk22k34",2)
print(result)
result=re.split(r"(\d+)","abc11kk22k34",2)
print(result)
['abc', 'kk', 'k', '']
['abc', '11', 'kk', '22', 'k', '34', '']
['abc', 'kk', 'k34']
['abc', '11', 'kk', '22', 'k34']
re.findall
- pattern 沒有捕獲組的話,該方法會返回所有匹配結果的list
- pattern 包含一個或多個捕獲組的話,list保存的結果是這些捕獲組的匹配結果,且list裏面的各項都是一個tuples
import re
result=re.findall(r"[a-z]+\d+","abc11kk22k34")
print(result)
result=re.findall(r"[a-z]+(\d+)","abc11kk22k34")
print(result)
result=re.findall(r"([a-z]+)(\d+)","abc11kk22k34")
print(result)
result=re.findall(r"([a-z]+)(\d+)()()()","abc11kk22k34")
print(result)
['abc11', 'kk22', 'k34']
['11', '22', '34']
[('abc', '11'), ('kk', '22'), ('k', '34')]
[('abc', '11', '', '', ''), ('kk', '22', '', '', ''), ('k', '34', '', '', '')]
re.finditer
返回一個迭代器,迭代器裏面的每個對象都是Match類型的數據
import re
result=re.finditer(r"\d+","abc11kk22k34")
for m in result:
print(m.group(0))
print()
result=re.finditer(r"(\d+)","abc11kk22k34")
for m in result:
print(m.group(0))
print(m.group(1))
re.compile
編譯正則,返回一個Pattern對象。 這樣做的目的是可以重複使用該正則模式對象
該Pattern類有如下方法
re.purge
清除正則表達式緩存
re.escape
轉義特殊字符,就是把有特殊意義的字符串轉義爲普通字符串