Java Regex Multiline问题

时间:2015-03-17 11:46:32

标签: java regex

我通过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,因为它是一个多线模式,我也希望涵盖换行符) 但是这种模式与String不匹配。如果我尝试删除正则表达式的LOGHEADER \ [END \]部分,我得到一个匹配,它包含整个字符串。我不明白为什么它不匹配原始的RegEx。

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

2 个答案:

答案 0 :(得分:1)

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

因此,您必须使用find()这种方式来捕获所有中间<!--LOGHEADER[START]/-->n<!--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());

答案 1 :(得分:0)

您实际上需要使用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());

}