Python正規表示式高階 零寬斷言

2021-10-09 18:59:48 字數 2329 閱讀 1646

1. 什麼是零寬斷言

有時候在使用正規表示式做匹配的時候,我們希望匹配乙個字串,這個字串的前面或後面需要是特定的內容,但我們又不想要前面或後面的這個特定的內容,這時候就需要零寬斷言的幫助了。所謂零寬斷言,簡單來說就是匹配乙個位置,這個位置滿足某個正則,但是不納入匹配結果的,所以叫「零寬」,而且這個位置的前面或後面需要滿足某種正則。

2、不同的零寬斷言

零寬斷言:正向反向兩類,每類又分為:**先行回顧後發

正**先行:簡稱正向先行斷言,語法:(?=exp),它斷言此位置的後面能匹配表示式exp,但不包含此位置;

如:a(?=\d),返回匹配字串中以數字為結尾的a字元。

正回顧後發:簡稱正向後發斷言,語法:(?<=exp),它斷言此位置的前面能匹配表示式exp;

如:(?<=\d)a,返回匹配字串中以數字為開頭的a字元。

負**先行:簡稱反向先行斷言,語法:(?!exp),它斷言此位置的後面不能匹配表示式exp;

如:a(?!\d),返回不匹配字串中以數字結尾的a字元。

負回顧後發:簡稱反向後發斷言,語法:(?3、零寬斷言的實踐與總結

示例:提取hello world

中hello world

目標字串:hello world

根據以上所說,當我們需要提取字串的時候,可以用斷言,思路如下:

首先,目標字串是hello world,那麼它可以歸納為.*

其次,目標字串前面有,既然是前面有,那麼根據四種斷言的含義,容易得出用正向後發斷言(?<=exp),將它放在目標字串前面,得到(?<=).*,進一步可以將div歸納為[a-za-z]+,從而得到(?<=).*

最後,目標字串後面有

,既然是後面有,那麼根據四種斷言的含義,容易得出用正向先行斷言(?=exp),將它放在目標字串後面,從而得到(?<=).*(?=)

進一步的,我們發現前後兩個斷言中都有[a-za-z]+,可以使用分組來避免書寫重複的內容:(?<=).*(?=),當然也可以使用命名分組,這裡就不展開了。

說到這裡,我歸納出了幾句書寫斷言的口訣:

前面有,正向後發(?<=exp),放前面;

後面有,正向先行(?=exp),放後面;

前面無,反向後發(?後面無,反向先行(?!exp),放後面。

請記住,這個前面和後面是針對目標字串,也就是你要提取出來的字串而言的。

4、實戰:

4.1、正向先行(?=exp):獲取字串中以ing結尾的字元:

4.2、正向後發(?<=exp):獲取字串中以do開頭的單詞後半部分:

4.3、反向先行(?!exp):匹配出字串中不是以ing結尾的單詞:

此處有雷,如果字串變成「do  run going hing」你再試試看,此處有待解決。

4.4、反向後發(?

此處有雷,同上

總結:主要原因是因為反向斷言不支援匹配不定長的表示式;

正規表示式 零寬斷言

零寬斷言的意思是 匹配寬度為零,滿足一定的條件 斷言 零寬斷言用於查詢在某些內容 但並不包括這些內容 之前或之後的東西,也就是說它們像 b 這樣的錨定作用,用於指定乙個位置,這個位置應該滿足一定的條件 即斷言 因此它們也被稱為零寬斷言。斷言用來宣告乙個應該為真的事實。正規表示式中只有當斷言為真時才會...

正規表示式 零寬斷言

今天在codewars.com做練習,遇到乙個正規表示式相關的題目regex password validation 題目很簡單,對字串進行校驗,規則如下 1.長度至少有6位 2.包含小寫字母 3.包含大寫字母 4.包含數字 5.僅由數字和字母組成 對於2.3.4這3個條件,沒辦法寫在乙個正則裡面,...

正規表示式 零寬斷言

接下來的四個用於查詢在某些內容 但並不包括這些內容 之前或之後的東西,也就是說它們像 b 那樣用於指定乙個位置,這個位置應該滿足一定的條件 斷言 因此它們也被稱為零寬斷言。最好還是拿例子來說明吧 exp 也叫零寬度正 先行斷言,它斷言自身出現的位置的後面能匹配表示式exp 比如 b w ing b ...