天天看點

使用正規表達式找出不包含特定字元串的條目概述

正規表達式中有前瞻(Lookahead)和後顧(Lookbehind)的概念,這兩個術語非常形象的描述了正則引擎的比對行為。需要注意一點,正規表達式中的前和後和我們一般了解的前後有點不同。一段文本,我們一般習慣把文本開頭的方向稱作“前面”,文本末尾方向稱為“後面”。但是對于正規表達式引擎來說,因為它是從文本頭部向尾部開始解析的(可以通過正則選項控制解析方向),是以對于文本尾部方向,稱為“前”,因為這個時候,正則引擎還沒走到那塊,而對文本頭部方向,則稱為“後”,因為正則引擎已經走過了那一塊地方。如下圖所示:

使用正規表達式找出不包含特定字元串的條目概述

所謂的前瞻就是在正規表達式比對到某個字元的時候,往“尚未解析過的文本”預先看一下,看是不是符合/不符合比對模式,而後顧,就是在正則引擎已經比對過的文本看看是不是符合/不符合比對模式。符合和不符合特定比對模式我們又稱為肯定式比對和否定式比對。

現代進階正規表達式引擎一般都支援都支援前瞻,對于後顧支援并不是很廣泛,是以我們這裡采用否定式前瞻來實作我們的需求。

測試資料:

例如上面這幾條簡單的日志條目,我們想實作兩個目标:

1. 把8号的資料過濾掉

2. 把那些不包含robots.txt字元串的條目給找出來(隻要Url中包含robots.txt的都給過濾掉)。

前瞻的文法是:

我們先來實作第一個目标——比對不以特定字元串開頭的條目。

這裡我們因為要排除一段連續的字元串,是以比對模式非常簡單,就是2009-07-08。實作如下:

接下來,我們來實作第二個目标——排除包含特定字元串的條目。

按照我們上面寫法,我照葫蘆畫瓢了一下:

這段正則用大白話描述就是:開頭任意字元,然後後面不要跟着robots.txt連續字元串,然後再跟着任意個字元,字元串結尾。

運作測試,結果發現:

使用正規表達式找出不包含特定字元串的條目概述

沒有達到我們想要的效果。這是為什麼呢?我們給上面的正規表達式加上兩個捕獲分組調試一下:

測試結果:

使用正規表達式找出不包含特定字元串的條目概述

我們看到,第一個分組啥都沒有比對到,而第二個分組卻比對了整個字元串。再回過頭來好好分析一下剛才那個正規表達式。實際上,當正則引擎解析到A區域的時候,就已經開始執行B區域的前瞻工作。這個時候發現當A區域為Null的時候比對成功——.*本來就允許比對空字元,前瞻條件又滿足,A區域後面緊跟着的是“2009”字元串,而并不是robots。是以整個比對過程成功比對到所有條目。

使用正規表達式找出不包含特定字元串的條目概述

分析出原因之後我們對上述的正則進行修正,将.*?移入前瞻表達式,如下:

測試結果:

使用正規表達式找出不包含特定字元串的條目概述

Bingo!

繼續閱讀