Python正則表達(dá)式教程之三:貪婪/非貪婪特性
之前已經(jīng)簡(jiǎn)單介紹了Python正則表達(dá)式的基礎(chǔ)與捕獲,那么在這一篇文章里,我將總結(jié)一下正則表達(dá)式的貪婪/非貪婪特性。
貪婪
默認(rèn)情況下,正則表達(dá)式將進(jìn)行貪婪匹配。所謂“貪婪”,其實(shí)就是在多種長(zhǎng)度的匹配字符串中,選擇較長(zhǎng)的那一個(gè)。例如,如下正則表達(dá)式本意是選出人物所說(shuō)的話,但是卻由于“貪婪”特性,出現(xiàn)了匹配不當(dāng):
>>> sentence = """You said "why?" and I say "I don't know".""" >>> re.findall(r'"(.*)"', sentence) ['why?" and I say "I don\'t know']
再比如,如下的幾個(gè)例子都說(shuō)明了正則表達(dá)式“貪婪”的特性:
>>> re.findall('hi*', 'hiiiii')
['hiiiii']
>>> re.findall('hi{2,}', 'hiiiii')
['hiiiii']
>>> re.findall('hi{1,3}', 'hiiiii')
['hiii']
非貪婪
當(dāng)我們期望正則表達(dá)式“非貪婪”地進(jìn)行匹配時(shí),需要通過(guò)語(yǔ)法明確說(shuō)明:
{2,5}? 捕獲2-5次,但是優(yōu)先次數(shù)少的匹配
在這里,問(wèn)號(hào)?可能會(huì)有些讓人犯暈,因?yàn)橹八呀?jīng)有了自己的含義:前面的匹配出現(xiàn)0次或1次。其實(shí),只要記住,當(dāng)問(wèn)號(hào)出現(xiàn)在表現(xiàn)不定次數(shù)的正則表達(dá)式部分之后時(shí),就表示非貪婪匹配。
還是上面的那幾個(gè)例子,用非貪婪匹配,則結(jié)果如下:
>>> re.findall('hi*?', 'hiiiii')
['h']
>>> re.findall('hi{2,}?', 'hiiiii')
['hii']
>>> re.findall('hi{1,3}?', 'hiiiii')
['hi']
另外一個(gè)例子中,使用非貪婪匹配,結(jié)果如下:
>>> sentence = """You said "why?" and I say "I don't know".""" >>> re.findall(r'"(.*?)"', sentence) ['why?', "I don't know"]
捕獲與非貪婪
嚴(yán)格來(lái)說(shuō),這一部分并不是非貪婪特性。但是由于其行為與非貪婪類似,所以為了方便記憶,就將其放在一起了。
(?=abc) 捕獲,但不消耗字符,且匹配abc
(?!abc) 捕獲,不消耗,且不匹配abc
在正則表達(dá)式匹配的過(guò)程中,其實(shí)存在“消耗字符”的過(guò)程,也就是說(shuō),一旦一個(gè)字符在匹配過(guò)程中被檢索(消耗)過(guò),后面的匹配就不會(huì)再檢索這一字符了。
知道這個(gè)特性有什么用呢?還是用例子說(shuō)明。比如,我們想找出字符串中出現(xiàn)過(guò)1次以上的單詞:
>>> sentence = "Oh what a day, what a lovely day!" >>> re.findall(r'\b(\w+)\b.*\b\1\b', sentence) ['what']
這樣的正則表達(dá)式顯然無(wú)法完成任務(wù)。為什么呢?原因就是,在第一個(gè)(\w+)匹配到what,并且其后的\1也匹配到第二個(gè)what的時(shí)候,“Oh what a day, what”這一段子串都已經(jīng)被正則表達(dá)式消耗了,所以之后的匹配,將直接從第二個(gè)what之后開(kāi)始。自然地,這里只能找出一個(gè)出現(xiàn)了兩次的單詞。
那么解決方案,就和上面提到的(?=abc)語(yǔ)法相關(guān)了。這樣的語(yǔ)法可以在分組匹配的同時(shí),不消耗字符串!所以,正確的書(shū)寫(xiě)方式應(yīng)該是:
>>> re.findall(r'\b(\w+)\b(?=.*\b\1\b)', sentence) ['what', 'a', 'day']
如果我們需要匹配一個(gè)至少包含兩個(gè)不同字母的單詞,則可以使用(?!abc)的語(yǔ)法:
>>> re.search(r'([a-z]).*(?!\1)[a-z]', 'aa', re.IGNORECASE) >>> re.search(r'([a-z]).*(?!\1)[a-z]', 'ab', re.IGNORECASE) <_sre.SRE_Match object; span=(0, 2), match='ab'>
總結(jié)
以上就是Python正則表達(dá)式中關(guān)于貪婪的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者使用python能能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,如果有疑問(wèn)大家可以留言交流。下一篇文章,我會(huì)繼續(xù)總結(jié)一下Python正則表達(dá)式re模塊的一些API的用法,請(qǐng)繼續(xù)關(guān)注腳本之家。
相關(guān)文章
Pytorch反向傳播中的細(xì)節(jié)-計(jì)算梯度時(shí)的默認(rèn)累加操作
這篇文章主要介紹了Pytorch反向傳播中的細(xì)節(jié)-計(jì)算梯度時(shí)的默認(rèn)累加操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Python數(shù)據(jù)類型相互轉(zhuǎn)換
當(dāng)涉及數(shù)據(jù)類型轉(zhuǎn)換時(shí),Python提供了多種內(nèi)置函數(shù)來(lái)執(zhí)行不同類型之間的轉(zhuǎn)換,本文主要介紹了Python數(shù)據(jù)類型相互轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
Python如何實(shí)現(xiàn)讀取csv文件時(shí)忽略文件的編碼格式
我們?cè)偃粘Wx取csv文件的時(shí)候經(jīng)常會(huì)發(fā)現(xiàn)csv文件的格式有多種,所以這篇文章為大家介紹了Python如何實(shí)現(xiàn)讀取csv文件時(shí)忽略文件的編碼格式吧2025-03-03
Python+PyQT5的子線程更新UI界面的實(shí)例
今天小編就為大家分享一篇Python+PyQT5的子線程更新UI界面的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2019-06-06
詳解python實(shí)現(xiàn)多張多格式圖片轉(zhuǎn)PDF并打包成exe
這篇文章主要為大家介紹了python實(shí)現(xiàn)多張多格式圖片轉(zhuǎn)PDF并打包成exe方式詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01
Python數(shù)據(jù)處理利器Pandas?DataFrame常用操作
這篇文章主要為大家介紹了Python數(shù)據(jù)處理利器Pandas?DataFrame,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06
Win10操作系統(tǒng)中PyTorch虛擬環(huán)境配置+PyCharm配置
本文主要介紹了Win10操作系統(tǒng)中PyTorch虛擬環(huán)境配置+PyCharm配置,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-09-09
Python OpenCV機(jī)器學(xué)習(xí)之圖像識(shí)別詳解
OpenCV中也提供了一些機(jī)器學(xué)習(xí)的方法,例如DNN等。本文將為大家詳細(xì)介紹一下OpenCV中利用機(jī)器學(xué)習(xí)實(shí)現(xiàn)的一些圖片識(shí)別功能:人臉識(shí)別、車(chē)牌識(shí)別等,感興趣的可以了解一下2022-01-01

