正規表示式中的斷言,作為高階應用出現,倒不是因為它有多難,而是概念比較抽象,不容易理解而已,今天就讓小菜通俗的講解一下。
如果不用斷言,以往用過的那些表示式,僅僅能獲取到有規律的字串,而不能獲取無規律的字串。
舉個例子,比如html原始碼中有***標籤,用以前的知識,我們只能確定原始碼中的和是固定不變的。因此,如果想獲取頁面標題(***),充其量只能寫乙個類似於這樣的表示式:.*,而這樣寫匹配出來的是完整的***標籤,並不是單純的頁面標題***。
想解決以上問題,就要用到斷言知識。
在講斷言之前,讀者應該先了解分組,這有助於理解斷言。
分組在正則中用()表示,根據小菜理解,分組的作用有兩個:
1 將某些規律看成是一組,然後進行組級別的重複,可以得到意想不到的效果。
2 分組之後,可以通過後向引用簡化表示式。
先來看第乙個作用,對於ip位址的匹配,簡單的可以寫為如下形式:
\d.\d.\d.\d
但仔細觀察,我們可以發現一定的規律,可以把.\d看成乙個整體,也就是把他們看成一組,再把這個組重複3次即可。表示式如下:
\d(.\d)
這樣一看,就比較簡潔了。
再來看第二個作用,就拿匹配***標籤來說,簡單的正則可以這樣寫:.*
可以看出,上邊表示式中有兩個title,完全一樣,其實可以通過分組簡寫。表示式如下:
<(title)>.*
這個例子實際上就是反向引用的實際應用。對於分組而言,整個表示式永遠算作第0組,在本例中,第0組是<(title)>.*,然後從左到右,依次為分組編號,因此,(title)是第1組。
用\1這種語法,可以引用某組的文字內容,\1當然就是引用第1組的文字內容了,這樣一來,就可以簡化正規表示式,只寫一次title,把它放在組裡,然後在後邊引用即可。
以此為啟發,我們可不可以簡化剛剛的ip位址正規表示式呢?原來的表示式為\d(.\d),裡邊的\d重複了兩次,如果利用後向引用簡化,表示式如下:
(\d)(.\1)
簡單的解釋下,把\d放在一組裡,表示為(\d),它是第1組,(.\1)是第2組,在第2組裡通過\1語法,後向引用了第1組的文字內容。
經過實際測試,會發現這樣寫是錯誤的,為什麼呢?
小菜一直在強調,後向引用,引用的僅僅是文字內容,而不是正規表示式!
也就是說,組中的內容一旦匹配成功,後向引用,引用的就是匹配成功後的內容,引用的是結果,而不是表示式
。因此,(\d)(.\1)這個表示式實際上匹配的是四個數都相同的ip位址,比如:123.123.123.123。
至此,讀者已經掌握了傳說中的後向引用,就這麼簡單。
接下來說說什麼是斷言。
所謂斷言,就是指明某個字串前邊或者後邊,將會出現滿足某種規律的字串。
就拿文章開篇的例子來說,我們想要的是***,它沒有規律,但是它前邊肯定會有,後邊肯定會有,這就足夠了。
想指定***前肯定會出現,就用正後發斷言,表示式:(?<=).*
向指定***後邊肯定會出現,就用正先行斷言,表示式:.*(?=)
兩個加在一起,就是(?<=).*(?=)
這樣就能匹配到***。
相信讀者看到這,已經蒙了,不用急,待小菜慢慢講來。
其實掌握了規律,就很簡單了,無論是先行還是後發,都是相對於***而言的,也就是相對於目標字串而言。
假如目標字串後邊有條件,可以理解為目標字串在前,就用先行斷言,放在目標字串之後。
假如目標字串前邊有條件,可以理解為目標字串在後,就用後發斷言,放在目標字串之前。
假如指定滿足某個條件,就是正。
假如指定不滿足某個條件,就是負。
斷言只是條件,幫你找到真正需要的字串,本身並不會匹配!
(?=x )
零寬度正先行斷言。僅當子表示式 x 在 此位置的右側匹配時才繼續匹配。例如,/w+(?=/d) 與後跟數字的單詞匹配,而不與該數字匹配。此構造不會回溯。
(?!x)
零寬度負先行斷言。僅當子表示式 x 不在 此位置的右側匹配時才繼續匹配。例如,例如,/w+(?!/d) 與後不跟數字的單詞匹配,而不與該數字匹配 。
(?<=x)
零寬度正後發斷言。僅當子表示式 x 在 此位置的左側匹配時才繼續匹配。例如,(?<=19)99 與跟在 19 後面的 99 的例項匹配。此構造不會回溯。
(?零寬度負後發斷言。僅當子表示式 x 不在此位置的左側匹配時才繼續匹配。例如,(?
從斷言的表達形式可以看出,它用的就是分組符號,只不過開頭都加了乙個問號,這個問號就是在說這是乙個非捕獲組,這個組沒有編號,不能用來後向引用,只能當做斷言。
教程到此結束,希望大家閱讀愉快!
正規表示式分組 斷言詳解
正規表示式中的斷言,作為高階應用出現,倒不是因為它有多難,而是概念比較抽象,不容易理解而已,今天就讓小菜通俗的講解一下。如果不用斷言,以往用過的那些表示式,僅僅能獲取到有規律的字串,而不能獲取無規律的字串。舉個例子,比如html原始碼中有 標籤,用以前的知識,我們只能確定原始碼中的和是固定不變的。因...
正規表示式中的分組斷言
正規表示式中的斷言,作為高階應用出現,倒不是因為它有多難,而是概念比較抽象,不容易理解而已,今天就讓小菜通俗的講解一下。如果不用斷言,以往用過的那些表示式,僅僅能獲取到有規律的字串,而不能獲取無規律的字串。舉個例子,比如html原始碼中有 標籤,用以前的知識,我們只能確定原始碼中的和是固定不變的。因...
正規表示式 分組 零寬斷言
import re a 123.123.123.aaa.aaa.aaa reg d 1 w 3 res re.search reg,a print res 引用分組上例中 1代表引用第乙個分組 d 3代表引用第三個分組 w import re a 123.234.345.456 b 123.123....