首頁 > 軟體

Python正規表示式以及常用匹配範例

2022-07-27 14:01:29

1 正規表示式物件

re.RegexObject

re.compile() 返回 RegexObject 物件。

re.MatchObject

group() 返回被 RE 匹配的字串。

  • start() 返回匹配開始的位置
  • end() 返回匹配結束的位置
  • span() 返回一個元組包含匹配 (開始,結束) 的位置

2 正規表示式修飾符 - 可選標誌

re.I 大小寫不敏感

re.L 做在地化識別(locale-aware)匹配

re.M 多行匹配,影響 ^ 和 $

re.S 使 . 匹配包括換行在內的所有字元

re.U 根據Unicode字元集解析字元。這個標誌影響 w, W, b, B.

re.X 該標誌通過給予你更靈活的格式以便你將正規表示式寫得更易於理解。

3 正規表示式字元意義

符號含義
^以什麼開頭
$以什麼結尾
.匹配任意字元,除了換行符
[…]用來表示一組字元,單獨列出:[amk] 匹配 ‘a’,‘m’或’k’
[^…]取反
*匹配0個或多個
+匹配1個或多個
?匹配0個或1個由前面的正規表示式定義的片段
{n}{ n}
{n,}精確匹配 n+ 個
{n,m}精確匹配 n 到m個
a|ba或b
()標記 組合
w匹配字母數位及下劃線,等價於 ‘[A-Za-z0-9_]’
W匹配非字母數位及下劃線,等價於’[^A-Za-z0-9_]
s匹配任意空白字元,等價於 [ fnrtv]。
S匹配任意非空字元 [^ fnrtv]
d匹配任意數位,等價於 [0-9].
D匹配任意非數位,等價於 [^0-9]。
A匹配字串開始
Z匹配字串結束,如果是存在換行,只匹配到換行前的結束字串。
z匹配字串結束
G匹配最後匹配完成的位置。
b單詞邊界
B非單詞邊界

組合使用

[ab]cde匹配 acde 或 bcde
abc[de]匹配 abcd 或 abce
[abcdef]匹配中括號內的任意一個字母
[0-9]匹配任何數位。類似於 [0123456789]
[a-z]匹配任何小寫字母
[A-Z]匹配任何大寫字母
[a-zA-Z0-9]匹配任何字母及數位
[^0-9]取反 匹配數位之外
.*任意一個字元 出現0次或多次 儘可能多的匹配
.*?只匹配符合條件的最少字元 儘可能少的匹配

re.match函數

re.match 嘗試從字串的起始位置匹配一個模式,如果不是起始位置匹配成功的話,match()就返回none。

re.match(pattern, string, flags=0)

pattern 匹配的正規表示式 string 要匹配的字串。 flags 標誌位,用於控制正規表示式的匹配方式,如:是否區分大小寫,多行匹配等等。

import re
#在起始位置匹配  匹配 www 是不是在開頭
print(re.match('www', 'www.aaa.com'))          # <re.Match object; span=(0, 3), match='www'>
print(re.match('www', 'www.aaa.com').span())   # (0, 3)
print(re.match('com', 'www.bbb.com'))          # None


line = "wo shi ni baba oo aa"
#最後的 .*就是後面所有的   re.M 多行匹配,影響 ^ 和 $     re.I 大小寫不敏感
matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)
if matchObj:
    print("matchObj.group() : ", matchObj.group())     #返回匹配到的整個表示式的字串
    print("matchObj.group(1) : ", matchObj.group(1))   #返回標記的1個() (.*)就是任意字元出現0個或多個 在這就是 wo
    print("matchObj.group(2) : ", matchObj.group(2))   #返回標記的2個() (.*?) 只匹配符合條件的最少字元 和.*是差不多的 就是 ni
else:
    print("No match!!")

#matchObj.group() :  wo shi ni baba oo aa
#matchObj.group(1) :  wo
#matchObj.group(2) :  ni

re.search方法

re.search 掃描整個字串並返回第一個成功的匹配。

re.search(pattern, string, flags=0)

print(re.search('ab', 'www.abcdef.com').span())  # (4, 6)
print(re.search('cc', 'www.abcdef.ccom').span()) # (11, 13)

替換re.sub

re.sub用於替換字串中的匹配項。

re.sub(pattern, repl, string, count=0, flags=0)

pattern : 正則中的模式字串。rep : 替換內容,也可為一個函數。 string : 要被查詢替換的原始字串。count : 模式匹配後替換的最大次數,預設 0 表示替換所有的匹配。

num1 = "a11a-b22b-c33c-d44d-e55e #sdsdasdas111da"
# re.sub(pattern, repl, string, count=0, flags=0)
##刪除#號之後的   將#號之後的所有 替換為空
num2 = re.sub(r'#.*$', "", num1)     
print(num2)                               #a11a-b22b-c33c-d44d-e55e
#  #D 匹配任意非數位  替換為空
num3 = re.sub(r'D', "", num1)          
print(num3)                               #1122334455111

def test(x):
    print(x)
    y = int(x.group())
    y *= 2
    return str(y)
# 內部呼叫test方法時 會把 匹配到的 資料以 re.Match的格式傳遞
print(re.sub(r'd+', test, p))

re.compile 函數

函數用於編譯正規表示式,生成一個正規表示式( Pattern )物件,供 match() 和 search() 這兩個函數使用。

re.compile(pattern,[flags])

pattern : 一個字串形式的正規表示式 flags : 可選,表示匹配模式,比如忽略大小寫,多行模式等

pattern = re.compile(r'([a-z]+) ([a-z]+) (.*)', re.I)
str1 = pattern.match('Wo shi ni Ba ba')
print(str1)              #<re.Match object; span=(0, 15), match='Wo shi ni Ba ba'>
print(str1.group(0))     #Wo shi ni Ba ba
print(str1.group(1))     #Wo
print(str1.group(2))     #shi
print(str1.group(3))     #ni Ba ba
print(str1.groups())     #('Wo', 'shi', 'ni Ba ba')
print(str1.span(1))      #(0, 2)
print(str1.span(2))      #(3, 6)
print(str1.span(3))      #(7, 15)

findall

在字串中找到正規表示式所匹配的所有子串,並返回一個列表,如果沒有找到匹配的,則返回空列表。

findall(string, [pos], [endpos])

string : 待匹配的字串。 pos : 可選引數,指定字串的起始位置,預設為 0。 endpos : 可選引數,指定字串的結束位置,預設為字串的長度。

pattern = re.compile(r'd+')  # 查詢數位
result1 = pattern.findall('aaa 123 bbb 456 ccc 789 ddd 222')
result2 = pattern.findall('aa11bbb22cc33dd44cc55', 0, 10)         # 0 10限制查詢的下標
print(result1)        #['123', '456', '789', '222']
print(result2)        #['11', '22']

re.finditer

和 findall 類似,在字串中找到正規表示式所匹配的所有子串,並把它們作為一個迭代器返回。

re.finditer(pattern, string, flags=0)

pattern 匹配的正規表示式 string 要匹配的字串。flags 標誌位

it = re.finditer(r"d+","aaa 123 bbb 456 ccc 789 ddd 222")
for match in it:
    print(match.group())
#123
#456
#789
#222

re.split

split 方法按照能夠匹配的子串將字串分割後返回列表

re.split(pattern, string, maxsplit=0, flags=0) maxsplit分隔次數,maxsplit=1 分隔一次,預設為 0,不限制次數。

m = re.split('W+', 'aaa 123 bbb 456 ccc 789 ddd 222')  #匹配非字母作為分割
print(m)   #['aaa', '123', 'bbb', '456', 'ccc', '789', 'ddd', '222']

m = re.split(' ','aaa 123 BBB 456 ccc 789 ddd 222')    #匹配非空格作為分割
print(m)   #['aaa', '123', 'BBB', '456', 'ccc', '789', 'ddd', '222']

m = re.split('[0-9]{3}','aaa 123 BBB 456 ccc 789 ddd 222')  #出現 3 個數位相連 為分割
print(m)  #['aaa ', ' BBB ', ' ccc ', ' ddd ', '']

練習:

#判斷使用者輸入是否是數位  fullmatch 全文匹配
import  re
num = input('請輸入一段數位:')
if re.fullmatch(r'd+(.?d+)?',num):   #d+ 數位匹配一個或多個 .?跳脫. 出現0 或1 次  後面再是數位   再把小數點和小數點後面的 作為整體  0次或1次
    print('是個數位')
    print(num)
else:
    print('不是一個數位')

m = 'aaa_123_bbb-456-CCC_789_ddd_222'
#r^D[a-z0-9A-Z_-]{3,13}     #以非數位開頭  數位字母下滑線組成的 長度4 到14 位的字串
b = re.match(r'^D[a-z0-9A-Z_-]{3,13}', m)
print(b.group())      #aaa_123_bbb-45
print(b.span())       #(0, 14)


#匹配遊戲
#r'^[0-9a-zA-Z_]{0,19}@[0-9a-zA-Z]{1,13}.[com,cn,net]{1,3}$'

#匹配手機號
#r'^1(3d|4[4-9]|5[0-35-9]|6[67]|7[013-8]|8[0-9]|9[0-9])d{8}$'

#匹配身份證號 前6位的地區:[1-9]開頭 d數位出現5個 (18|19|20)d{2} 出生的年份18几几 19几几 20几几 1800-2099  月份 ((0|[1-9])|(10|11|12)) 日期 (([0-2][1-9])|10|20|30|31) 最後是3個數位, 再加一位 數位或者Xx結尾
#r'^[1-9]d{5}(18|19|20)d{2}((0|[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)d{3}[0-9Xx]$'

補充:Python的re模組兩個比較常用的方法

1、sub()方法:將目標字串中符合正則匹配的字元替換成我們想要的字元,最終返回結果是一個新的字串。

語法:sub(pattern,replace,string,count,flags)

引數說明:

   1、pattern:表示匹配模式

   2、replace:表示要替換成的字串

   3、string:目標字串

   4、count:可選引數,表示模式匹配後替換的最大次數,預設值為0,表示替換所有匹配。

   5、flags:可選引數,用於控制匹配方式,常用的例如:re.I,表示無視字母大小寫匹配。

例:

import re
pattern = "d+"
string = "Abcde123acb888acd"
#將字串中的數位替換成」成功「兩個字
newstr = re.sub(pattern,"成功",string)
print(newstr)

列印結果:

Abcde成功acb成功acd

增加替換次數:

import re
pattern = "d+"
string = "Abcde123acb888acd"
newstr = re.sub(pattern,"成功",string,1)
print(newstr)

列印結果:

Abcde成功acb888acd

2、spilit()方法:將目標字串按照正則匹配的字串進行切割,最終返回結果是一個列表。

語法:re.split(pattern,string,maxSplit,flags)

引數說明:

1、pattern:正則匹配模式。

2、string:目標字串。

3、maxSplit:可選引數,按照正則匹配字串切割的最大切割次數,如果不寫表示最大切割。

4、flags:可選引數,用於控制匹配方式,常用的例如:re.I,表示無視字母大小寫匹配。

例:

import re
pattern = "d+"
string = "Abcde123acb888acd"
newstr = re.split(pattern,string)
print(newstr)

列印結果:

['Abcde', 'acb', 'acd']

增加切割次數maxSplit

import re
pattern = "d+"
string = "Abcde123acb888acd"
newstr = re.split(pattern,string,1)
print(newstr)

列印結果:

['Abcde', 'acb888acd']

總結

到此這篇關於Python正規表示式以及常用匹配的文章就介紹到這了,更多相關Python正規表示式內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com