Python正則re模塊詳解

Cooking Regex微信公衆號
正則表達式學習

 

目錄

re.match

re.fullmatch 

re.search 

 re.sub

re.subn

re.split 

 re.findall

re.finditer 

 re.compile

 re.purge

 re.escape


閱讀本文章時,已默認您對正則表達式有了一定的瞭解。該教程是對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

 轉義特殊字符,就是把有特殊意義的字符串轉義爲普通字符串

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章