【问题标题】:Java regex that searches multi-line text excluding some string搜索不包括某些字符串的多行文本的 Java 正则表达式
【发布时间】:2014-01-15 10:01:12
【问题描述】:

我有一些代码:

String test = "int measure; \n" +
              "void introduce() { \n" +
              "while (line != null) { \n" +
              "if(measure > 0) { \n" +
              "System.out.println(smile); \n" +
                "} \n" +
              "}";  

String functions = "^.*(?!(catch|if|while|try|return|finally|new|throw)).*$";
Pattern patternFunctions = Pattern.compile(functions);
Matcher matcherFunctions = patternFunctions.matcher(test);
while(matcherFunctions.find()) 
          System.out.println(matcherFunctions.group());

这应该打印除第三和第四行之外的所有行,因为它们包含“if”和“while”字样。但实际上它什么也没打印。 每一个帮助将不胜感激。 谢谢。

更新:

谢谢大家的回答!你的例子很有效。我还有一个问题:在负前瞻之后,我想插入条件.*\\(.*\\).*\\{,这意味着文本包含.*<negotiation>.*(.*).*{,以一种简单的方式,它应该从我的String test 中打印第二行。我尝试了这个正则表达式(?m)^.*(?!(catch|if|while|try|return|finally|new|throw).\\(.*\\).*\\{)*$,但它不能以正确的方式工作。你有什么建议?

【问题讨论】:

    标签: java regex


    【解决方案1】:

    尝试启用多行模式,如下所示:https://stackoverflow.com/a/6143347/584663

    并且,在否定前瞻中包含点:https://stackoverflow.com/a/2387072/584663

    产生:(?m)^((?!(catch|if|while|try|return|finally|new|throw)).)*$

    【讨论】:

    • 这是一个负前瞻,而不是往后看。
    【解决方案2】:

    它没有给你任何输出,因为你的正则表达式不正确。

    您需要删除开头的.*,并在您的Negative Lookahead周围放置一个捕获组或非捕获组,并重建结尾.*,以便将点.放在前面你的最后一个括号和量词 * 放在 $ 锚之前的最后一个括号之后。

    您需要使用m 修饰符(多行)使^$ 锚点匹配每行的开头/结尾。我添加了i 修饰符的使用,用于不区分大小写的匹配。

    String functions = "(?im)^(?:(?!(?:catch|if|while|try|return|finally|new|throw)).)*$";
    

    正则表达式:

    (?im)           set flags for this block (case-insensitive) 
                    (with ^ and $ matching start and end of line)
     ^              the beginning of a "line"
     (?:            group, but do not capture (0 or more times)
      (?!           look ahead to see if there is not:
      (?:           group, but do not capture:
        catch       'catch'
       |            OR
        if          'if'
       |            OR
        while       'while'
       |            OR
        try         'try'
       |            OR
        return      'return'
       |            OR
        finally     'finally'
       |            OR
        new         'new'
       |            OR
        throw       'throw'
      )             end of grouping
      )             end of look-ahead
      .             any character except \n
     )*             end of grouping
     $              before an optional \n, and the end of a "line"
    

    Working demo

    【讨论】:

      【解决方案3】:
      1. "^.*(?!(catch..."删除第一个.*,因为它允许ifwhile
      2. 使用 multiline 标志编译您的正则表达式。

      工作代码:

      String functions = "^((?!(catch|if|while|try|return|finally|new|throw))).*$";
      Pattern patternFunctions = Pattern.compile(functions, Pattern.MULTILINE);
      Matcher matcherFunctions = patternFunctions.matcher(test);
      

      更多关于java.util.regex.Pattern.Multiline

      在多行模式下,表达式 ^ 和 $ 匹配紧随其后或紧随其后 分别在行终止符或输入结束之前 顺序。默认情况下,这些表达式只匹配开头和 整个输入序列的结束。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2020-08-25
        • 1970-01-01
        • 2021-06-25
        • 1970-01-01
        • 2011-05-05
        • 2023-03-14
        • 1970-01-01
        相关资源
        最近更新 更多