2011-03-23 42 views
2
input1="caused/VBN by/IN thyroid disorder" 

要求:找字"caused"後跟斜槓後跟任意數量的大寫字母的 - 而不是後跟空格+ "by/IN排除模式正則表達式不工作

在上面的例子中,"caused/VBN"後面跟着" by/IN",所以'引起'不應該匹配。

input2="caused/VBN thyroid disorder" 

"by/IN"不遵循造成的,所以應該匹配

regex="caused/[A-Z]+(?![\\s]+by/IN)" 

caused/[A-Z]+ - 字 '引發' +/+一個或多個大寫字母
(?![\\s]+by) - 負前瞻 - 不匹配空間和

下面是一個簡單的方法,我用來測試

public static void main(String[] args){ 
    String input = "caused/VBN by/IN thyroid disorder"; 

    String regex = "caused/[A-Z]+(?![\\s]+by/IN)"; 

    Pattern pattern = Pattern.compile(regex); 
    Matcher matcher = pattern.matcher(input); 

    while(matcher.find()){ 
     System.out.println(matcher.group()); 
    } 

輸出:caused/VB

我不明白爲什麼我負超前的正則表達式是行不通的。

回答

7

您需要在您的正則表達式字邊界:

String regex = "caused/[A-Z]+\\b(?![\\s]+by/IN)"; 

沒有它,你可以得到一個匹配,但不正是您期望:

 
"caused/VBN by/IN thyroid disorder"; 
^^^^^^^^^ 
this matches because "N by" doesn't match "[\\s]+by" 
+0

'\\ s'周圍的括號是不必要的,不是? – 2011-03-23 22:57:19

+0

是的,他們完全沒有必要。 – 2011-03-23 23:18:18

+0

+1 - 請注意,所有格加也可以做到這一點:'由/導致/ [A-Z] ++(?![\ s] +)。 – ridgerunner 2011-03-24 01:28:34

3

字符類[] +比賽將被調整(通過回溯),以便前瞻將匹配。

你所要做的就是停止回溯,使表達式[] +完全匹配。
這可以通過幾種不同的方式完成。

  1. 一種正先行,隨後消費
    "caused(?=(/[A-Z]+))\\1(?!\\s+by/IN)"

  2. 一個獨立的子表達式
    "caused(?>/[A-Z]+)(?!\\s+by/IN)"

  3. 甲possesive量詞
    "caused/[A-Z]++(?!\\s+by/IN)"

+0

感謝您的回答 您的量化建議非常棒 - 我需要了解一下您的其他建議。非常感謝! – dsatish 2011-03-24 16:26:36