正規表示式分組 斷言詳解

2021-07-02 11:54:34 字數 2247 閱讀 1852

正規表示式中的斷言,作為高階應用出現,倒不是因為它有多難,而是概念比較抽象,不容易理解而已,今天就讓小菜通俗的講解一下。

如果不用斷言,以往用過的那些表示式,僅僅能獲取到有規律的字串,而不能獲取無規律的字串。

舉個例子,比如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....