正則表達式之負向零寬斷言

2018-08-04 15:31 更新

怎么查找不是某個字符或不在某個字符類里的字符的方法(反義)我們之前已經(jīng)提過了。但是如果我們的目的不是去匹配某個字符,而是只想要該字符是否出現(xiàn)過,怎么辦?例如,如果我們想要查找的單詞中出現(xiàn)了字母q,但是字母q的后面跟著的不是字母u的話,我們可以嘗試:

\b\w*q[^u]\w*\b匹配包含后面不是字母u的字母q的單詞。但是如果多做測試(或者你思維足夠敏銳,直接就觀察出來了),你會發(fā)現(xiàn),如果q出現(xiàn)在單詞的結(jié)尾的話,像Iraq,Benq,這個表達式就會出錯。這是因為[^u]總要匹配一個字符,所以如果q是單詞的最后一個字符的話,后面的[^u]將會匹配q后面的單詞分隔符(可能是空格,或者是句號或其它的什么),后面的\w*\b將會匹配下一個單詞,于是\b\w*q[^u]\w*\b就能匹配整個Iraq fighting負向零寬斷言能解決這樣的問題,因為它只匹配一個位置,并不消費任何字符?,F(xiàn)在,我們可以這樣來解決這個問題:\b\w*q(?!u)\w*\b。

零寬度負預測先行斷言(?!exp),斷言此位置的后面不能匹配表達式exp。例如:\d{3}(?!\d)匹配三位數(shù)字,而且這三位數(shù)字的后面不能是數(shù)字;\b((?!abc)\w)+\b匹配不包含連續(xù)字符串a(chǎn)bc的單詞。

同理,我們可以用(?<!exp),零寬度負回顧后發(fā)斷言斷言此位置的前面不能匹配表達式exp(?<![a-z])\d{7}匹配前面不是小寫字母的七位數(shù)字

一個更復雜的例子:(?<=<(\w+)>).*(?=<\/\1>)匹配不包含屬性的簡單HTML標簽內(nèi)里的內(nèi)容。(?<=<(\w+)>)指定了這樣的前綴被尖括號括起來的單詞(比如可能是<b>),然后是.*(任意的字符串),最后是一個后綴(?=<\/\1>)。注意后綴里的\/,它用到了前面提過的字符轉(zhuǎn)義;\1則是一個反向引用,引用的正是捕獲的第一組,前面的(\w+)匹配的內(nèi)容,這樣如果前綴實際上是<b>的話,后綴就是</b>了。整個表達式匹配的是<b>和</b>之間的內(nèi)容(再次提醒,不包括前綴和后綴本身)。

注解:

  • 請詳細分析表達式(?<=<(\w+)>).*(?=<\/\1>),這個表達式最能表現(xiàn)零寬斷言的真正用途。


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號