【问题标题】:Java Regex Multiline issueJava 正则表达式多行问题
【发布时间】:2015-03-17 11:46:32
【问题描述】:

我通过 apache commons FileUtils.readFileToString 从文件中读取了一个字符串,格式如下:

<!--LOGHEADER[START]/-->
<!--HELP[Manual modification of the header may cause parsing problem!]/-->
<!--LOGGINGVERSION[2.0.7.1006]/-->
<!--NAME[./log/defaultTrace_00.trc]/-->
<!--PATTERN[defaultTrace_00.trc]/-->
<!--FORMATTER[com.sap.tc.logging.ListFormatter]/-->
<!--ENCODING[UTF8]/-->
<!--FILESET[0, 20, 10485760]/-->
<!--PREVIOUSFILE[defaultTrace_00.19.trc]/-->
<!--NEXTFILE[defaultTrace_00.1.trc]/-->
<!--ENGINEVERSION[7.31.3301.368426.20141205114648]/-->
<!--LOGHEADER[END]/-->
#2.0#2015 03 04 11:04:19:687#+0100#Debug#...(few lines to follow)

我正在尝试过滤掉 LOGHEADER[START] 和 LOGHEADER[END] 行之间的所有内容。因此我创建了一个 java 正则表达式:

String fileContent = FileUtils.readFileToString(file);
String logheader = "LOGHEADER\\[START\\].*LOGHEADER\\[END\\]";
Pattern p = Pattern.compile(logheader, Pattern.DOTALL);
Matcher m = p.matcher(fileContent);
System.out.println(m.matches());

(Dotall 因为它是多行模式,我也想涵盖换行符) 但是,此模式与字符串不匹配。如果我尝试删除正则表达式的 LOGHEADER\[END\] 部分,我会得到一个匹配项,其中包含整个字符串。我不明白为什么它与原始 RegEx 不匹配。

感谢任何帮助 - 非常感谢!

【问题讨论】:

  • 正则表达式可能不是这里工作的最佳工具。既然你知道边界,只需使用BufferedReader 并使用.readLine()
  • 你的预期输出是什么?
  • 或者,如果您想依赖 RegEx,请使用 this 工具之一尝试您的 RegEx
  • 你读过matches() 做了什么吗?您确定要使用此方法吗?也许您正在寻找find().* 也应该是不情愿的。

标签: java regex


【解决方案1】:

关于这个 Java matches() 方法要记住的重要一点是,您的正则表达式必须匹配整行。

因此,您必须以这种方式使用find() 来捕获&lt;!--LOGHEADER[START]/--&gt;n&lt;!--LOGHEADER[END]/-- 之间的所有内容:

String logheader = "(?<=LOGHEADER\\[START\\]/-->).*(?=<!--LOGHEADER\\[END\\])";
        Pattern p = Pattern.compile(logheader, Pattern.DOTALL);
        Matcher m = p.matcher(fileContent);
        while(m.find()) {
         System.out.println(m.group());
       }

或者,按照您建议的逻辑(仅使用matches),我们需要添加^.*.*$

String logheader = "^.*LOGHEADER\\[START\\].*LOGHEADER\\[END\\].*$";
Pattern p = Pattern.compile(logheader, Pattern.DOTALL);
Matcher m = p.matcher(fileContent);
System.out.println(m.matches());

【讨论】:

    【解决方案2】:

    您实际上需要使用PatternMatcher 类以及find 方法。下面的正则表达式将获取存在于LOGHEADER[START]LOGHEADER[END] 之间的所有行。

    String s = "<!--LOGHEADER[START]/-->\n" + 
            "<!--HELP[Manual modification of the header may cause parsing problem!]/-->\n" + 
            "<!--LOGGINGVERSION[2.0.7.1006]/-->\n" + 
            "<!--NAME[./log/defaultTrace_00.trc]/-->\n" + 
            "<!--PATTERN[defaultTrace_00.trc]/-->\n" + 
            "<!--FORMATTER[com.sap.tc.logging.ListFormatter]/-->\n" + 
            "<!--ENCODING[UTF8]/-->\n" + 
            "<!--FILESET[0, 20, 10485760]/-->\n" + 
            "<!--PREVIOUSFILE[defaultTrace_00.19.trc]/-->\n" + 
            "<!--NEXTFILE[defaultTrace_00.1.trc]/-->\n" + 
            "<!--ENGINEVERSION[7.31.3301.368426.20141205114648]/-->\n" + 
            "<!--LOGHEADER[END]/-->\n" + 
            "#2.0#2015 03 04 11:04:19:687#+0100#Debug#...(few lines to follow)";
    Matcher m = Pattern.compile("(?s)\\bLOGHEADER\\[START\\][^\\n]*\\n(.*?)\\n[^\\n]*\\bLOGHEADER\\[END\\]").matcher(s);
    while(m.find())
    {
    
    System.out.println(m.group(1));
    
    }
    

    输出:

    <!--HELP[Manual modification of the header may cause parsing problem!]/-->
    <!--LOGGINGVERSION[2.0.7.1006]/-->
    <!--NAME[./log/defaultTrace_00.trc]/-->
    <!--PATTERN[defaultTrace_00.trc]/-->
    <!--FORMATTER[com.sap.tc.logging.ListFormatter]/-->
    <!--ENCODING[UTF8]/-->
    <!--FILESET[0, 20, 10485760]/-->
    <!--PREVIOUSFILE[defaultTrace_00.19.trc]/-->
    <!--NEXTFILE[defaultTrace_00.1.trc]/-->
    <!--ENGINEVERSION[7.31.3301.368426.20141205114648]/-->
    

    如果您还想匹配LOGHEADER 行,那么捕获组将是不必要的。

    Matcher m = Pattern.compile("(?s)[^\\n]*\\bLOGHEADER\\[START\\].*?\\bLOGHEADER\\[END\\][^\\n]*").matcher(s);
    while(m.find())
    {
    
    System.out.println(m.group());
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-04
      相关资源
      最近更新 更多