常常咱們會遇到想找出不包含某個字符串的文本,程序員最容易想到的是在正則表達式裏使用,^(hede)
來過濾」hede」字串,但這種寫法是錯誤的。咱們能夠這樣寫:[^hede]
,但這樣的正則表達式徹底是另一個意思,它的意思是字符串裏不能包含‘h’,‘e’,‘d’三個但字符。那什麼樣的正則表達式能過濾出不包含完整「hello」字串的信息呢?php
事實上,說正則表達式裏不支持逆向匹配並非百分之百的正確。就像這個問題,咱們就可使用否認式查找來模擬出逆向匹配,從而解決咱們的問題:程序員
^((?!hede).)*$
上面這個表達式就能過濾出不包含‘hede’字串的信息。我上面也說了,這種寫法並非正則表達式「擅長」的用法,但它是能夠這樣用的。web
解釋
一個字符串是由n個字符組成的。在每一個字符以前和以後,都有一個空字符。這樣,一個由n個字符組成的字符串就有n+1個空字符串。咱們來看一下「ABhedeCD」這個字符串:正則表達式
+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+ S = |e1| A |e2| B |e3| h |e4| e |e5| d |e6| e |e7| C |e8| D |e9| +--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+---+--+ index 0 1 2 3 4 5 6 7
全部的e編號的位置都是空字符。表達式(?!hede).
會往前查找,看看前面是否是沒有「hede」字串,若是沒有(是其它字符),那麼.
(點號)就會匹配這些其它字符。這種正則表達式的「查找」也叫作「zero-width-assertions」(零寬度斷言),由於它不會捕獲任何的字符,只是判斷。express
在上面的例子裏,每一個空字符都會檢查其前面的字符串是否不是‘hede’,若是不是,這.
(點號)就是匹配捕捉這個字符。表達式(?!hede).
只執行一次,因此,咱們將這個表達式用括號包裹成組(group),而後用*
(星號)修飾——匹配0次或屢次:((?!hede).)*
。post
你能夠理解,正則表達式((?!hede).)*
匹配字符串"ABhedeCD"
的結果false,由於在e3
位置,(?!hede)
匹配不合格,它以前有"hede"
字符串,也就是包含了指定的字符串。spa
在正則表達式裏, ?!
是否認式向前查找,它幫咱們解決了字符串「不包含」匹配的問題。.net