正則表達式-不包含某個字符串

     在使用正則表達式的場合,經常有這種需求,就是匹配一個不包含某個子串的子符串。好比說,我要從「eabcdfgh」獲得"cd"以前的子串。有些人可能會寫:正則表達式

([^cd]*)ide

這種寫法是完全錯誤的,由於[]中的是集合,也就是說,[^cd]表示不等於c或者d,而不是cd。下面的程序中沒有cd,但eab仍是被匹配出來了。spa

  
  
           
  
  
  1. String s = "([^cd]*)"
  2. Match m = Regex.Match("eabcfgh", s); 
  3. MessageBox.Show(m.Value);//eab 
  4. MessageBox.Show(m.Groups[1].Value);//eab 

上面這種寫法是錯的比較離譜的,正常青年通常均可以免這種錯誤。在特殊狀況下,正則表達式能夠這麼寫,並且效率是比較高的。字符串

([/s/S]*cd)get

先說明下/s/S是表示匹配任何字符。所謂特殊狀況,就是我知道這個字符串中必有cd的存在。假如,個人要求是匹配不包含cd的部分(爲了描述方便,只匹配cd以前的部分),也就是說,當cd不存在時,應該把整個字符串都取出來。string

  
  
           
  
  
  1. String s = "((.(?!cd))*.)"
  2. //String s = "([/s/S]*cd)"; 
  3. Match m = Regex.Match("eabcdfgh", s); 
  4. MessageBox.Show(m.Value);//eab 
  5. MessageBox.Show(m.Groups[1].Value);//eab 

這種寫法終於符合要求了。不過值得一提的是,相較前一種而言,它的效率比較低。it

回顧一下相關的語法:class

(?:子表達式)         定義非捕獲組。效率

  
  
           
  
  
  1. //定義非捕獲組 
  2. String s = "e(?:ab)(.*)"
  3. Match m = Regex.Match("eabcd", s); 
  4. MessageBox.Show(m.Value);//eabcd 
  5. MessageBox.Show(m.Groups[1].Value);//cd 

ab是被匹配的,可是它所在的組沒有被捕獲,Group[1]是cd語法

(?=子表達式)       零寬度正預測先行斷言。

  
  
           
  
  
  1. //零寬度正預測先行斷言 
  2. //String s = "b(cd|de)(.*)"; 
  3. String s = "b(?=cd|de)(.*)"
  4. Match m = Regex.Match("eabcdfg", s); 
  5. MessageBox.Show(m.Value); 
  6. MessageBox.Show(m.Groups[1].Value);//區別 cd  cdfg 

這種寫法和註釋掉的寫法是有區別的,區別就是「零寬度」,這種寫法會被捕獲,也就是不佔一個Group。

(?!子表達式)       零寬度負預測先行斷言。

!表示非,就是不包含,一樣是零寬度,不會被捕獲。

 

(?<=子表達式)    零寬度正回顧後發斷言。

例:(?<=19)\d{2}\b

「1851 1999 1950 1905 2003」中的「99」、「50」和「05」

(?<!子表達式)     零寬度負回顧後發斷言。

例:(?<!19)\d{2}\b

「1851 1999 1950 1905 2003」中的「51」和「03」

參考文章: http://msdn.microsoft.com/zh-cn/library/az24scfc.aspx

相關文章
相關標籤/搜索