2011-03-23 45 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