一文帶你輕松搞定Python正則匹配
一、前言
日常工作中,不可避免需要進(jìn)行文件及內(nèi)容的查找,替換操作,python的正則匹配無(wú)疑是專門針對(duì)改場(chǎng)景而出現(xiàn)的,靈活地運(yùn)用可以極大地提高效率,下圖是本文內(nèi)容概覽。
二、正則表達(dá)式符號(hào)
對(duì)于所有的正則匹配表達(dá)式,都可由4部分組成:基礎(chǔ)字符,次數(shù)匹配,位置匹配,分組匹配,即
正則匹配表達(dá)式= 基礎(chǔ)字符(必選)+次數(shù)匹配(可選)+位置匹配(可選)+分組匹配(可選)
2.1 基礎(chǔ)字符
基礎(chǔ)字符主要是對(duì)應(yīng)與具體的匹配對(duì)象,常用的如下表,其中涉及有特殊含義的字符,如.,*,^,$等,如果要匹配該字符本身,需要使用轉(zhuǎn)移符號(hào)"\"。
代碼示例:
import re string="lucky^ /696/ ^money \Healthy **" pattern_num=re.compile("\d") #匹配數(shù)字 num=pattern_num.findall(string) pattern_letter=re.compile("\w") #匹配字母或數(shù)字 letter=pattern_letter.findall(string) pattern_blank=re.compile("\s") #匹配空格 blank=pattern_blank.findall(string) pattern_slash=re.compile(r"\\") #匹配反斜杠\ slash=pattern_slash.findall(string) pattern_tri=re.compile("\^") #匹配特殊字符^ tri=pattern_tri.findall(string) print("num:%s\nletter:%s\nblank:%s\nslash:%s\ntri:%s"%(num,letter,blank,slash,tri))
查詢結(jié)果,注意\s表示單個(gè)空格,連續(xù)兩個(gè)空格是作為兩個(gè)結(jié)果,單反斜杠\的結(jié)果slash表示用“\\”,如果使用print函數(shù)打印查看實(shí)際是單斜杠\
2.2 匹配次數(shù)
在設(shè)置了具體匹配字符后,還可以對(duì)字符匹配的數(shù)量進(jìn)行限制,即在匹配字符后面加上匹配次數(shù)字符即可
代碼示例
import re string="lucky^ \/696/\ ^money// \Healthy 12**" pattern_num=re.compile("\d+") #匹配至少1個(gè)數(shù)字 num=pattern_num.findall(string) pattern_letter=re.compile("\w{4,5}") #匹配4-5個(gè)字母或數(shù)字 letter=pattern_letter.findall(string) pattern_blank=re.compile("\s{3}") #匹配3個(gè)連續(xù)的空格 blank=pattern_blank.findall(string) pattern_slash=re.compile(r"/{2,}") #匹配至少兩個(gè)反斜杠// slash=pattern_slash.findall(string) pattern_tri=re.compile("\d|\^") #匹配數(shù)字或特殊字符^ tri=pattern_tri.findall(string) print("num:%s\nletter:%s\nblank:%s\nslash:%s\ntri:%s"%(num,letter,blank,slash,tri))
查詢結(jié)果
2.3 匹配位置
同限制匹配字符的數(shù)量類似,可以設(shè)置匹配字符的位置,如指定開頭或結(jié)尾的字符
代碼示例
import re string="luckyhappy happy-dog /happy, happy_test ^money Healthy 12**happy**" pattern_head=re.compile("^luc") #匹配以luc開頭的字符 head=pattern_head.findall(string) #匹配成功 print("head",head) pattern_head1=re.compile("^money") #匹配以money開頭的字符 head1=pattern_head1.findall(string) #匹配失敗 print("head1",head1) pattern_tail=re.compile("\*$") #匹配結(jié)尾為*的字符 tail=pattern_tail.findall(string) #匹配成功 print("tail",tail) pattern_tail1=re.compile("money$") #匹配結(jié)尾為money的字符 tail1=pattern_tail1.findall(string) #匹配失敗 print("tail1",tail1) pattern_limit=re.compile(r"\bhappy\b") #匹配字符串中的單詞happy,如果happy左右兩側(cè)都是字母數(shù)字下劃線,注意前面需加r limit=pattern_limit.findall(string) #匹配成功,其中l(wèi)uckyhappy和happy_test不屬于匹配成功的對(duì)象 print("limit",limit)
結(jié)果
2.3.1 ^與\A,$與\Z
注意^和\A,$和\Z看似都匹配開頭和結(jié)尾,但在多行模式下存在差異,如下例子
import re str = "Have a wonderful\nhope in python\nstudy" #str內(nèi)容為3行,\n表示換行 # 使用^ print("^ in slnle line:",re.findall("^hope", str)) # 默認(rèn)單行模式,執(zhí)照字符串的行首匹配,找不到匹配項(xiàng) print("^ in multiple line:",re.findall("^hope", str, re.MULTILINE)) # 在多行模式下找到匹配項(xiàng),會(huì)匹配其他行的行首 # 使用\A print("\A in slnle line:",re.findall("\Ahope", str)) # 默認(rèn)單行模式,執(zhí)照字符串的行首匹配,找不到匹配項(xiàng) print("\A in multiple line:",re.findall("\Ahope", str, re.MULTILINE)) # 在多行模式下,依然不會(huì)匹配其他行的行首 # 使用$ print("$ in slnle line:",re.findall("python$", str)) # 默認(rèn)單行模式,執(zhí)照字符串的行首匹配,找不到匹配項(xiàng) print("$ in multiple line:",re.findall("python$", str, re.MULTILINE)) # 在多行模式下找到匹配項(xiàng),會(huì)匹配其他行的行首 # 使用\Z print("\Z in slnle line:",re.findall("python\Z", str)) # 默認(rèn)單行模式,執(zhí)照字符串的行首匹配,找不到匹配項(xiàng) print("\Z in multiple line:",re.findall("python\Z", str, re.MULTILINE)) # 在多行模式下,依然不會(huì)匹配其他行的行首
匹配結(jié)果
2.4 分組匹配
示例代碼
import re str = "Zyp Have a 626 wonderful hello hope in python *** study" pattern=re.compile("(Zyp).*([0-9]{3}).*(\*{3})") #創(chuàng)建3個(gè)group查詢 result=pattern.match(str) print("All content:",result.group(0)) #group[0]為原始字符串 print("Name:",result.group(1)) #查找的結(jié)果下標(biāo)從1開始 print("Value",result.group(2)) print("Count:",result.group(3))
結(jié)果
三、匹配函數(shù)
前面內(nèi)容已對(duì)匹配表達(dá)式進(jìn)行了介紹,下面將介紹一些常用的查找函數(shù),查找的條件也就是匹配表達(dá)式。主要有match,search,findall,finditer,sub,下表是它們之間的差異
3.1 compile
compile函數(shù)不是匹配函數(shù),主要是用于生成pattern對(duì)象,供匹配函數(shù)使用,好處是可以將該規(guī)則重復(fù)使用。
語(yǔ)法: re.compile(pattern, flags=0) pattern : 匹配規(guī)則 flags : 標(biāo)志位,默認(rèn)為0,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。
關(guān)于其中的flags,可配置如下值
- re.I 忽略大小寫
- re.L 表示特殊字符集 \w, \W, \b, \B, \s, \S 依賴于當(dāng)前環(huán)境
- re.M 多行模式
- re.S 即為 . 并且包括換行符在內(nèi)的任意字符(. 不包括換行符)
- re.U 表示特殊字符集 \w, \W, \b, \B, \d, \D, \s, \S 依賴于 Unicode 字符屬性數(shù)據(jù)庫(kù)
- re.X 為了增加可讀性,忽略空格和 # 后面的注釋
示例代碼
import re str ="Zyp Have a 626 wonderful hello hope in python *** study" str2="Hwq Have a 888 wonderful hello hope in python * study" pattern=re.compile("(\w{3}).*([0-9]{3}).*(\*)") #創(chuàng)建3個(gè)group查詢 result=pattern.match(str) result2=pattern.match(str2) #直接復(fù)用pattern,直接修改用于匹配的對(duì)象 print("Name:",result.group(1),result2.group(1)) #查找的結(jié)果下標(biāo)從1開始 print("Value",result.group(2),result2.group(2)) print("Count:",result.group(3),result2.group(3))
匹配結(jié)果
3.2 match
match需要注意的是匹配是從行首位置開始,如果行首位置不存在匹配的結(jié)果,縱使后面存在可匹配的字符,依舊搜索不到,并且如果行首匹配成功,則直接返回結(jié)果,只進(jìn)行一次匹配操作,不會(huì)繼續(xù)對(duì)后面的進(jìn)行匹配,
語(yǔ)法: re.match(pattern, string, flags=0) pattern : 匹配規(guī)則 string : 用于正則匹配的字符串。 flags : 標(biāo)志位,默認(rèn)為0,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。
代碼示例
匹配結(jié)果,返回的結(jié)果為一個(gè)match對(duì)象
3.3 search
search作用與match類似,只進(jìn)行一次匹配,但不會(huì)限制于在行首位置匹配,可在任意位置進(jìn)行匹配,仍以match中的字符串示例
語(yǔ)法: re.search(pattern, string, flags=0) pattern : 匹配規(guī)則 string : 用于正則匹配的字符串。 flags : 標(biāo)志位,默認(rèn)為0,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。
代碼示例
匹配結(jié)果,兩個(gè)字符串str,str1都匹配到了符合規(guī)則的結(jié)果,返回的結(jié)果為一個(gè)match對(duì)象
3.4 findall
findall從名稱可看出是查詢所有符合的匹配項(xiàng),并且返回的結(jié)果類型為列表,仍以相同的例子為例,多加了一個(gè)1314
語(yǔ)法: re.findall(pattern, string, flags=0) pattern : 匹配規(guī)則 string : 用于正則匹配的字符串。 flags : 標(biāo)志位,默認(rèn)為0,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。
示例代碼
匹配結(jié)果,兩個(gè)字符串的查詢結(jié)果一致
3.5 finditer
finditer作用與findall相同,也是查詢所有符合條件的結(jié)果,區(qū)別是返回的結(jié)果為迭代器,而不是列表。同時(shí)迭代表結(jié)果的查看可通過(guò)函數(shù)group或groups進(jìn)行查看,但groups查看結(jié)果,必須匹配規(guī)則pattern中設(shè)置了分組形式,否則查找的內(nèi)容為空元組。
語(yǔ)法: re.finditer(pattern, string, flags=0) pattern : 匹配規(guī)則 string : 用于正則匹配的字符串。 flags : 標(biāo)志位,默認(rèn)為0,用于控制正則表達(dá)式的匹配方式,如:是否區(qū)分大小寫,多行匹配等等。
示例代碼
匹配結(jié)果
3.6 sub
語(yǔ)法: re.sub(pattern, repl, string, count=0, flags=0) pattern : 匹配規(guī)則 repl : 用于替換匹配結(jié)果的新字符串。 string : 用于正則匹配的字符串。 count : 設(shè)置匹配后的替換次數(shù),默認(rèn) 0 表示替換所有的匹配結(jié)果。 flags : 編譯時(shí)用的匹配模式。
代碼示例
import re str ="Zyp Have a 626 wonderful hello hope 520 in python 1314*** study" #str存在2個(gè)3位,1個(gè)4位的數(shù)字, pattern=re.compile("[0-9]{3}") #匹配一個(gè)3位的數(shù)字 result=re.sub(pattern,"999",str,count=2) #對(duì)于查詢到的3位數(shù)字用999替換,只替換2次 print("result:",result)
替換結(jié)果,原先3位的數(shù)字前面2個(gè)都已替換位999,因只替換2次,第3個(gè)1314不進(jìn)行替換
四、常用場(chǎng)景
下面將針對(duì)一些常用的場(chǎng)景提供對(duì)應(yīng)的匹配規(guī)則
正則表達(dá)式 含義 [3] 匹配數(shù)字“3”,即指定匹配的具體數(shù)字 [c] 匹配字母“c”,即指定匹配的具體字符 [0-9] 匹配一個(gè)數(shù)字 [^0-9] 匹配一個(gè)除0-9外的字符 [a-z] 匹配一個(gè)小寫字母 [A-Z] 匹配一個(gè)大寫字母 [a-zA-Z] 匹配一個(gè)字母 [^a-z] 匹配一個(gè)非小寫字母的字符 ^\d{4}-\d{1,2}-\d{1,2} 匹配以“-”形式分隔的日期,如2024-5-2 \d{18}|\d{17}[X]$ 匹配出身份證號(hào)碼 \d+\.\d+\.\d+\.\d+ 匹配IP地址 ^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$ 匹配電子郵箱
總結(jié)
到此這篇關(guān)于Python正則匹配的文章就介紹到這了,更多相關(guān)Python正則匹配內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章

Python機(jī)器學(xué)習(xí)pytorch交叉熵?fù)p失函數(shù)的深刻理解

Python多線程與異步處理在HTTP請(qǐng)求中的應(yīng)用方式

詳解python中return和print的區(qū)別和用途

利用Python實(shí)現(xiàn)網(wǎng)絡(luò)測(cè)試的腳本分享

Python調(diào)用百度AI實(shí)現(xiàn)圖片上表格識(shí)別功能

Python?range函數(shù)生成一系列連續(xù)整數(shù)的內(nèi)部機(jī)制解析

python3中datetime庫(kù),time庫(kù)以及pandas中的時(shí)間函數(shù)區(qū)別與詳解