天天看點

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

測試資料:

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

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

1、把8号的資料過濾掉;

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

前瞻的文法是:(?!比對模式)

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

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

用Expresso我們可以看到結果确實過濾掉8号的資料。

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

按照我們上面寫法,我照葫蘆畫瓢了一下:^.*?(?!robots\.txt).*?$

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

運作測試,結果發現:

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

沒有達到我們想要的效果。這是為什麼呢?我們給上面的正規表達式加上兩個捕獲分組調試一下:^(.*?)(?!robots\.txt)(.*?)$

測試結果:

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

我們看到,第一個分組啥都沒有比對到,而第二個分組卻比對了整個字元串。再回過頭來好好分析一下剛才那個正規表達式。

實際上,當正則引擎解析到A區 域的時候,就已經開始執行B區域的前瞻工作。這個時候發現當A區域為Null的時候比對成功——.*本來就允許比對空字元,前瞻條件又滿足,A區域後面緊 跟着的是“2009”字元串,而并不是robots。是以整個比對過程成功比對到所有條目。

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串

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

測試結果:

java正規表達式 不包含_java使用正規表達式比對不包含某個規則的字元串