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 ...