Python正則表達(dá)式常用梳理

目錄

[1鞭呕、 什么是正則表達(dá)式.

[2、 正則表達(dá)式語(yǔ)法結(jié)構(gòu).

[2.1. 入門案例:了解正則表達(dá)式.

[2.3. python中的正則表達(dá)式模塊re
[2.3.1 字符串查詢匹配的函數(shù):

[2.3.2 字符串拆分替換的函數(shù):

[2.4. 正則表達(dá)式中的元字符.

[2.5. 正則表達(dá)式中的量詞.

[2.6. 正則表達(dá)式中的范圍匹配.

[2.7. 正則表達(dá)式中的分組.

[2.8. 正則表達(dá)式中的特殊用法.

[2.9 正則表達(dá)式的貪婪模式和懶惰模式.

1.什么是正則表達(dá)式

正則表達(dá)式:也稱為規(guī)則表達(dá)式,英文名稱Regular Expression, 我們?cè)诔绦蛑薪?jīng)常會(huì)縮寫為 regex 或者 regexp, 專門用于進(jìn)行文本檢索、匹配、替換等操作的一種技術(shù)惜论,
注意:正則表達(dá)式是一種獨(dú)立的技術(shù),并不是某編程語(yǔ)言獨(dú)有的

正則表達(dá)式止喷,是一種特殊的符號(hào)馆类,這樣的符號(hào)是需要解釋才能使用的,也就是需要正則表達(dá)式引擎來(lái)進(jìn)行解釋弹谁,目前正則表達(dá)式的引擎主要分三種:DFA,NFA,POSIX NFA/ 有興趣了解正則表達(dá)式引擎的童鞋乾巧,可以自己查看資料。

2.正則表達(dá)式語(yǔ)法結(jié)構(gòu)

接下來(lái)预愤,我們開始了解這樣一個(gè)神秘的可以類似人類神經(jīng)網(wǎng)絡(luò)一樣思考問(wèn)題的技術(shù)的語(yǔ)法結(jié)構(gòu)
注意:我們通過(guò)python程序進(jìn)行測(cè)試沟于,但是正則表達(dá)式的語(yǔ)法結(jié)構(gòu)在各種語(yǔ)言環(huán)境中都是通用的。

2.1入門案例:了解正則表達(dá)式

我們通過(guò)一個(gè)簡(jiǎn)單的案例入手:通常情況下植康,我們會(huì)驗(yàn)證用戶輸入的手機(jī)號(hào)碼是否合法旷太,是否 156/186/188開頭的手機(jī)號(hào)碼,如果按照常規(guī)驗(yàn)證手段,就需要對(duì)字符串進(jìn)行拆分處理供璧,然后逐步匹配
重要提示:python中提供了re模塊存崖,包含了正則表達(dá)式的所有功能,專門用于進(jìn)行正則表達(dá)式的處理睡毒;
案例:

def validatephone(phone):
#定義正則表達(dá)式来惧,python中的正則表達(dá)式還是一個(gè)字符串,是以 r 開頭的字符串
regexp = r"^(156|186|188)\d{8}$"
#開始驗(yàn)證
if re.match(regexp,phone):
    return "手機(jī)號(hào)碼合法”
else:
    return "手機(jī)號(hào)碼只能以156/186/188開頭演顾,并且每一個(gè)字符都是數(shù)字供搀,請(qǐng)檢查"
#開始驗(yàn)證
print(validatephone(userphone))

執(zhí)行上面的代碼,我們得到正常驗(yàn)證的結(jié)果钠至,大家可以自己試一試趁曼,
使用正則表達(dá)式之后會(huì)使程序變得非常簡(jiǎn)潔,接下里棕洋,我們繼續(xù)正則表達(dá)式的表演

2.3python中的正則表達(dá)式模塊re

2.3.1字符串查詢匹配的函數(shù):

函數(shù)                                               描述
re ,match(reg, info)      用于在開始位置匹配目標(biāo)字符串info中符合正則表達(dá)式reg的字符,匹配成功會(huì)返回一個(gè)match對(duì)象乒融,匹配不成功返回None

re, search(reg,info)    掃描整個(gè)字符串info掰盘,使用正則表達(dá)式reg進(jìn)行匹配,匹配成功返回匹配的第一個(gè)match對(duì)象赞季,匹配不成功返回None

re,findall(reg,info)    掃描整個(gè)字符串info愧捕,將符合整個(gè)表達(dá)式reg的字符全部提取出來(lái)存放在列表中返回

re , fullmatch(reg,info)   掃描整個(gè)字符串,如果整個(gè)字符串都包含在正則表達(dá)式表示的范圍中申钩,返回整個(gè)字符串次绘,否則返回None

re, finditer(reg,info)   掃描整個(gè)字符串,將匹配到的字符保存在一個(gè)可以遍歷的列表中

參考官方re.py源代碼如下:


image.png

image.png

2.3.2字符串拆分替換的函數(shù):

函數(shù)                                      描述
re.split(reg,string)       使用指定的正則表達(dá)式reg匹配的字符撒遣,將字符串string 拆分成一個(gè)字符串列表邮偎,如:re.split(r."\s+",info),表示使用一個(gè)或者多個(gè)空白字符對(duì)字符串info進(jìn)行拆分,并返回一個(gè)拆分后的字符串列表

re,sub(reg,repl,string)  只用指定的字符串repl來(lái)替換字符串string中匹配正則表達(dá)式reg的字符

接下來(lái)义黎,我們進(jìn)入正則表達(dá)式干貨部分

2.4正則表達(dá)式中的元字符

在使用正則表達(dá)式的過(guò)程中禾进,一些包含特殊含義的字符,用于表示字符串中一些特殊的位置非常重要廉涕,我們先簡(jiǎn)單了解一下一些常用的元字符

元字符                                    描述
^                表示匹配字符串的開頭位置的字符
$               表示匹配字符串的結(jié)束位置的字符
.                 表示匹配任意一個(gè)字符
\d              匹配一個(gè)數(shù)字字符
\D              匹配一個(gè)非數(shù)字字符
\s               匹配一個(gè)空白字符
\S               匹配一個(gè)非空白字符
\w                匹配一個(gè)數(shù)字/字母/下劃線中任意一個(gè)字符
\W                匹配一個(gè)非數(shù)字字母下劃線的任意一個(gè)字符
\b                 匹配一個(gè)單詞的邊界
\B                      匹配不是單詞的開頭或者結(jié)束位置

上干貨:代碼案例

導(dǎo)入正則表達(dá)式模塊
import re
#定義測(cè)試文本字符串泻云,我們后續(xù)再這段文本中查詢數(shù)據(jù)
msg1 = '''pyhton is an easy to learn, powerful programming language.
it has efficient high-level data  structures and a simple but effective approach to object-oriented programming.
python'selegant syntax and dynamic typing,together with its interpreted nature,
make it an ideal language for scripting and rapid application development in many areas on most platforms.
'''
msg2 = 'hello'
msg3 = 'hello%'
#定義正則表達(dá)式,匹配字符串開頭是否為pyhton
regStart = r"efficient"
#從字符串開始位置匹配狐蜕,是否包含符合正則表達(dá)式的內(nèi)容宠纯,返回匹配到的字符串的match對(duì)象
print(re.match(regStart,msg1))
#掃描整個(gè)字符串,是否包含符合正則表達(dá)式的內(nèi)容层释,返回匹配到的第一個(gè)字符串的match對(duì)象
print(re.search(regStart,msg1))
#掃描整個(gè)字符串婆瓜,是否包含符合正則表達(dá)式的內(nèi)容,返回匹配到的所有字符串列表
print(re,findall(regStart,msg1))
#掃描整個(gè)字符串湃累,是否包含符合正則表達(dá)式的內(nèi)容太勃救,返回匹配到的字符串的迭代對(duì)象
for r in re.finditer(regStart ,msg1):
print("->"+ r.group())
#掃描整個(gè)字符串碍讨,是否包含在正則表達(dá)式匹配到的內(nèi)容中,是則返回整個(gè)字符串蒙秒,否則返回None
print(re.fullmatch(r"\w*",msg2))
print(re,fullmatch(r"\w*",msg3))
上述代碼執(zhí)行結(jié)果如下:
None
<sre.SRE_MATCH object;span=(66,75)match = 'efficient'>
['efficient']
->efficient
<sre.SRE_Match object; span = (0,5),match = 'hello'>
None

2.5正則表達(dá)式中的量詞

正則表達(dá)式中的量詞勃黍,是用于限定數(shù)量的特殊字符

量詞                                         描述
x*                   用于匹配符號(hào)*前面的字符出現(xiàn)0次或者多次
x+                 用于匹配符號(hào)+前面的字符出現(xiàn)1次或者多次
x?                   用于匹配符號(hào)?前面的字符出現(xiàn)0次或者1次
x{n}                  用于匹配符號(hào){n}前面的字符出現(xiàn)n次
x{m,n}             用于匹配符號(hào){m,n}前面的字符出現(xiàn)至少m次晕讲,最多n次
x{n,}                     用于匹配符號(hào){n,}前面的字符出現(xiàn)至少n次

接著上代碼干貨:


image.png

image.png

2.6.正則表達(dá)式中的范圍匹配

在正則表達(dá)式中覆获,針對(duì)字符的匹配,出了快捷的元字符的匹配瓢省,還有另一種使用方括號(hào)進(jìn)行的范圍匹配方式弄息,具體如下:

范圍                                    描述
[0-9]   用于匹配一個(gè)0~9之間的數(shù)字,等價(jià)于\d
[^0-9]  用于匹配一個(gè)非數(shù)字字符勤婚,等價(jià)于\D
[3-6]   用于匹配一個(gè)3~6之間的數(shù)字
[a-z]   用于匹配一個(gè)a~z之間的字母
[A-Z]   用于匹配一個(gè)A~Z之間的字母
[a-f]   用于匹配一個(gè)a~f之間的字母
[a-zA-Z]    用于匹配一個(gè)a~z或者A-Z之間的字母摹量,匹配任意一個(gè)字母
[a-zA-Z0-9] 用于匹配一個(gè)字母或者數(shù)字
[a-zA-Z0-9_]    用于匹配一個(gè)字母或者數(shù)字或者下劃線,等價(jià)于\w
[^a-zA-Z0-9_]   用于匹配一個(gè)非字母或者數(shù)字或者下劃線馒胆,等價(jià)于\W

注意:不要使用【0-120】來(lái)表示0~120之間的數(shù)字缨称,這是錯(cuò)誤的,整理測(cè)試代碼如下:


image.png

2.7.正則表達(dá)式中的分組

正則表達(dá)式主要是用于進(jìn)行字符串檢索匹配操作的利器祝迂,在一次完整的匹配過(guò)程中睦尽,可以將匹配到的結(jié)果進(jìn)行分組,這樣就更加的細(xì)化了我們隊(duì)匹配結(jié)果的操作
正則表達(dá)式通過(guò)圓括號(hào)()進(jìn)行分組型雳,以提取匹配結(jié)果的部分結(jié)果
常用的兩種分組

分組                                      描述
(expression)         使用圓括號(hào)直接分組当凡;正則表達(dá)式本身匹配的結(jié)果就是一個(gè)組,可以通過(guò)group()或者group(0)獲染兰蟆沿量;然后正則表達(dá)式中包含的圓括號(hào)就是按照順序從1開始編號(hào)的小組
(?P<name>expression)    使用圓括號(hào)分組冤荆,然后給當(dāng)前的圓括號(hào)表示的小組命名為name欧瘪,可以通過(guò)group(name) 進(jìn)行數(shù)據(jù)的獲取
image.png

image.png

image.png

2.8.正則表達(dá)式中的特殊用法

使用分組的同,會(huì)有一些特殊的使用方式如下:


同時(shí)

2.9正則表達(dá)式的貪婪模式和懶惰模式

在某些情況下匙赞,我們匹配的字符串出現(xiàn)一些特殊的規(guī)律是佛掖,就會(huì)出現(xiàn)匹配結(jié)果不盡如人意的意外情況
如:在下面的字符串中,將div標(biāo)簽中的所有內(nèi)容獲取出來(lái)
如:在下面的字符串中涌庭,將div標(biāo)簽中的所有內(nèi)容獲取出來(lái)
<div>內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>
此時(shí)芥被,我們想到的是,使用<div>作為關(guān)鍵信息進(jìn)行正則表達(dá)式的定義坐榆,如下
regexp = r"<div>.*</div>"
本意是使用上述代碼來(lái)完成div開始標(biāo)簽和結(jié)束標(biāo)簽之間的內(nèi)容匹配拴魄,但是,匹配的結(jié)果如下
<div> [內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2] </div>
我們可以看到,上面匹配的結(jié)果匹中,是將字符串開頭的<div>標(biāo)簽和字符串結(jié)束的</div>當(dāng)成了匹配元素疚宇,對(duì)包含在中間的內(nèi)容直接進(jìn)行了匹配仆邓,也就得到了我們期望之外的結(jié)果:
內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2
上述就是我們要說(shuō)的正則表達(dá)式的第一種模式:貪婪模式
貪婪模式:正則表達(dá)式匹配的一種模式,速度快,但是匹配的內(nèi)容會(huì)從字符串兩頭向中間搜索匹配(比較貪婪~)思劳,一旦匹配選中盈罐,就不繼續(xù)向字符串中間搜索了媒殉,過(guò)程如下:
開始:<div>內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>

第一次匹配:【<div>內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>】

第二次匹配<div>【內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2】</div>

匹配到正則中需要的結(jié)果梁沧,不再繼續(xù)匹配,直接返回匹配結(jié)果如下:
內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2
明顯貪婪模式某些情況下重虑,不是我們想要的践付,所以出現(xiàn)了另一種模式:懶惰模式
懶惰模式:正則表達(dá)式匹配的另一種模式,會(huì)首先搜索匹配正則表達(dá)式開始位置的字符缺厉,然后逐步向字符串的結(jié)束位置查找永高,一旦找到匹配的就返回,然后接著查找
regexp = r"<div>.*?</div>"
開始:<div>內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>

第一次匹配:【<div>】?jī)?nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>

第二次匹配【<div>內(nèi)容1</div>】<p>這本來(lái)是不需要的內(nèi)容</p><div>內(nèi)容2</div>

匹配到正則中需要的結(jié)果:內(nèi)容1

繼續(xù)向后查找

第三次匹配<div>內(nèi)容1</div>【<p>這本來(lái)是不需要的內(nèi)容</p>】<div>內(nèi)容2</div>

第四次匹配<div>內(nèi)容1</div><p>這本來(lái)是不需要的內(nèi)容</p>【<div>內(nèi)容2</div>】

匹配到正則中需要的結(jié)果:內(nèi)容2

查找字符串結(jié)束提针!
正則表達(dá)式匹配的兩種模式:貪婪模式乏梁、懶惰模式
貪婪模式:從目標(biāo)字符串的兩頭開始搜索,一次盡可能多的匹配符合條件的字符串关贵,但是有可能會(huì)匹配到不需要的內(nèi)容,正則表達(dá)式中的元字符卖毁、量詞揖曾、范圍等都模式是貪婪匹配模式,使用的時(shí)候一定要注意分析結(jié)果亥啦,如:<div>.</div>就是一個(gè)貪婪模式炭剪,用于匹配<div>和</div>之間所有的字符
懶惰模式:從目標(biāo)字符串按照順序從頭到位進(jìn)行檢索匹配,盡可能的檢索到最小范圍的匹配結(jié)果翔脱,語(yǔ)法結(jié)構(gòu)是在貪婪模式的表達(dá)式后面加上一個(gè)符號(hào)?即可奴拦,如<div>.
?</div>就是一個(gè)懶惰模式的正則,用于僅僅匹配最小范圍的<div>和</div>之間的內(nèi)容
不論貪婪模式還是懶惰模式届吁,都有適合自己使用的地方错妖,大家一定要根據(jù)實(shí)際需求進(jìn)行解決方案的確定

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疚沐,隨后出現(xiàn)的幾起案子暂氯,更是在濱河造成了極大的恐慌,老刑警劉巖亮蛔,帶你破解...
    沈念sama閱讀 219,039評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件痴施,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)辣吃,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,426評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門动遭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人神得,你說(shuō)我怎么就攤上這事厘惦。” “怎么了循头?”我有些...
    開封第一講書人閱讀 165,417評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵绵估,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我卡骂,道長(zhǎng)国裳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,868評(píng)論 1 295
  • 正文 為了忘掉前任全跨,我火速辦了婚禮缝左,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘浓若。我一直安慰自己渺杉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,892評(píng)論 6 392
  • 文/花漫 我一把揭開白布挪钓。 她就那樣靜靜地躺著是越,像睡著了一般。 火紅的嫁衣襯著肌膚如雪碌上。 梳的紋絲不亂的頭發(fā)上倚评,一...
    開封第一講書人閱讀 51,692評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音馏予,去河邊找鬼天梧。 笑死,一個(gè)胖子當(dāng)著我的面吹牛霞丧,可吹牛的內(nèi)容都是我干的呢岗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,416評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開眼蛹尝,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼后豫!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起突那,我...
    開封第一講書人閱讀 39,326評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤硬贯,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后陨收,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饭豹,經(jīng)...
    沈念sama閱讀 45,782評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸵赖,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,957評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了拄衰。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片它褪。...
    茶點(diǎn)故事閱讀 40,102評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖翘悉,靈堂內(nèi)的尸體忽然破棺而出茫打,到底是詐尸還是另有隱情,我是刑警寧澤妖混,帶...
    沈念sama閱讀 35,790評(píng)論 5 346
  • 正文 年R本政府宣布老赤,位于F島的核電站,受9級(jí)特大地震影響制市,放射性物質(zhì)發(fā)生泄漏抬旺。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,442評(píng)論 3 331
  • 文/蒙蒙 一祥楣、第九天 我趴在偏房一處隱蔽的房頂上張望开财。 院中可真熱鬧,春花似錦误褪、人聲如沸责鳍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,996評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)历葛。三九已至,卻和暖如春嘀略,著一層夾襖步出監(jiān)牢的瞬間恤溶,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,113評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工屎鳍, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人问裕。 一個(gè)月前我還...
    沈念sama閱讀 48,332評(píng)論 3 373
  • 正文 我出身青樓逮壁,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親粮宛。 傳聞我的和親對(duì)象是個(gè)殘疾皇子窥淆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,044評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容