【问题标题】:Negative lookahead regex not working负前瞻正则表达式不起作用
【发布时间】:2011-07-21 17:22:23
【问题描述】:
input1="caused/VBN by/IN thyroid disorder"

要求:查找单词"caused",该单词后跟斜线,后跟任意数量的大写字母——并且后面不跟空格+"by/IN

在上面的例子中,"caused/VBN" 后面跟着" by/IN",所以 'caused' 不应该匹配。

input2="caused/VBN thyroid disorder" 

"by/IN" 不跟随导致,所以它应该匹配

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

caused/[A-Z]+ -- 单词 'caused' + / + 一个或多个大写字母
(?![\\s]+by) -- 负前瞻 - 不匹配空格和 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

我不明白为什么我的负前瞻正则表达式不起作用。

【问题讨论】:

    标签: java regex regex-negation regex-lookarounds


    【解决方案1】:

    将调整字符类 []+ 匹配(通过回溯),以便前瞻匹配。

    您要做的是停止回溯,以便表达式 []+ 完全匹配。
    这可以通过几种不同的方式来完成。

    1. 积极的前瞻,然后是消费
      "caused(?=(/[A-Z]+))\\1(?!\\s+by/IN)"

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

    3. 占有量词
      "caused/[A-Z]++(?!\\s+by/IN)"

    【讨论】:

    • 感谢您的回答您的所有格量词建议很棒——我需要阅读一下以了解您的其他建议。非常感谢!
    【解决方案2】:

    您需要在正则表达式中包含单词边界:

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

    没有它你可以得到匹配,但不是你所期望的:

    “由/IN 甲状腺疾病引起/VBN”; ^^^^^^^^^ 这匹配因为“N by”不匹配“[\\s]+by”

    【讨论】:

    • \\s 周围的括号是不必要的,不是吗?
    • 是的,它们完全没有必要。
    • +1 - 请注意,所有格加号也可以解决问题:caused/[A-Z]++(?![\s]+by/IN)
    • 感谢您的 cmets。 >> 这匹配因为 "N by" 不匹配 "[\\s]+by" 这是有道理的!
    猜你喜欢
    • 1970-01-01
    • 2017-04-22
    • 1970-01-01
    • 2021-10-11
    • 2011-10-14
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多