Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java正则表达式:捕获令牌之间的多行序列_Java_Regex - Fatal编程技术网

java正则表达式:捕获令牌之间的多行序列

java正则表达式:捕获令牌之间的多行序列,java,regex,Java,Regex,我正在努力使用正则表达式将日志文件拆分为日志序列,以便匹配这些序列中的模式。 日志格式为: timestamp fieldA fieldB fieldn log message1 timestamp fieldA fieldB fieldn log message2 log message2bis timestamp fieldA fieldB fieldn log message3 时间戳regex是已知的 我想提取时间戳之间的每个日志序列(可能是多行)。我想保留时间戳 我想在同一时间保

我正在努力使用正则表达式将日志文件拆分为日志序列,以便匹配这些序列中的模式。 日志格式为:

timestamp fieldA fieldB fieldn log message1 
timestamp fieldA fieldB fieldn log message2
log message2bis
timestamp fieldA fieldB fieldn log message3 
时间戳regex是已知的

我想提取时间戳之间的每个日志序列(可能是多行)。我想保留时间戳

我想在同一时间保持准确的行数

我需要的是如何修饰时间戳模式,使其按日志顺序分割我的日志文件。我无法将整个文件拆分为字符串,因为文件内容是在CharBuffer中提供的

下面是将使用此日志序列匹配器的示例方法:

private void matches(File f, CharBuffer cb) {
    Matcher sequenceBreak = sequencePattern.matcher(cb);    // sequence matcher
    int lines = 1;
    int sequences = 0;

    while (sequenceBreak.find()) {
        sequences++;

        String sequence = sequenceBreak.group();
        if (filter.accept(sequence)) {
            System.out.println(f + ":" + lines + ":" + sequence);                
        }

        //count lines
        Matcher lineBreak = LINE_PATTERN.matcher(sequence);
        while (lineBreak.find()) {
            lines++;
        }

        if (sequenceBreak.end() == cb.limit()) {
            break;
        }
    }        
}

我在您的代码中没有看到任何正则表达式,但这里有一个提示:

通过defilt,正则表达式中的点
与除新行以外的所有内容匹配。如果希望它匹配新行,则需要将其作为参数


另一种匹配新行的方法是使用预定义的组
\s
,该组匹配
[\t\n\x0B\f\r]

听起来像是希望正则表达式匹配整个日志序列,从时间戳到最后一行的末尾,包括行分隔符。假设每个日志序列后面紧跟着另一个日志序列,但最后一个日志序列后面紧跟着另一个日志序列,您应该能够使用时间戳的先行查找来查找序列的结尾

Pattern sequencePattern = pattern.compile(
    "^timestamp.*?(?=timestamp|\z)",
    Pattern.DOTALL | Pattern.MULTILINE);
如果这不够快或不够准确,那么这应该更有效:

Pattern sequencePattern = pattern.compile(
    "^timestamp.*+(?:(?:\r\n|[\r\n])(?!timestamp).*+)*+(?:\r\n|[\r\n])?",
    Pattern.MULTILINE);

当然,我假设您将用真正的timestamp regex替换
timestamp
。出于好奇,您是否考虑过使用扫描仪的方法进行此操作?在我看来,它可以为您节省大量工作。

如果我正确理解您的问题,您希望使用正则表达式拆分文件,但不能使用Java内置的split()方法。在这种情况下,只需编写自己的Split()方法

迭代所有正则表达式匹配项。对于第一个匹配,存储时间戳和匹配的结束位置。对于后续匹配,在存储的上一个匹配的结束位置和当前匹配的开始位置之间获取文本,并将其与上一个匹配关联。然后存储当前匹配的时间戳和结束位置。循环之后,在存储的最后一个匹配的结束位置和文件结尾之间获取文本,并将其与最后一个匹配相关联


使用一个只匹配时间戳的正则表达式,并使用一点过程代码来获取时间戳之间的文本,将(远)比尝试使用一个匹配时间戳和下一个时间戳之前的所有内容的正则表达式更有效。

您可能还需要标志模式。multilithanks Jan,我曾想用这样的方法来解决这个问题,但我希望“神奇的正则表达式能解决这个问题”。艾伦的回答与你所能得到的“神奇”一样接近。但是如果性能和可维护性对您很重要,我建议使用简单的“timestamp”regex,让过程代码完成我在回答中描述的工作。有“魔力”的正则表达式是一些人认为自己邪恶的原因。谢谢艾伦,我很高兴你理解了我问题的意义,因为即使是我自己的眼睛,它看起来也很模糊。。。你是否建议我放弃正则表达式而选择扫描仪,代码更简单,工作也更好。