我正在努力使用正则表达式将日志文件拆分为日志序列,以匹配这些序列中的模式。 日志格式为:
timestamp fieldA fieldB fieldn log message1
timestamp fieldA fieldB fieldn log message2
log message2bis
timestamp fieldA fieldB fieldn log message3
时间戳正则表达式已知。
我想在时间戳之间提取每个日志序列(潜在的多行)。我想保留时间戳。
我希望在同一时间保持准确的行数。
我需要的是如何在日志序列中装饰时间戳模式以使其分割我的日志文件。我无法将整个文件拆分为String,因为文件内容是在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;
}
}
}
答案 0 :(得分:1)
听起来你希望正则表达式匹配整个日志序列,从时间戳到最后一行的结尾,包括行分隔符。假设每个日志序列但最后一个日志序列后面紧跟另一个日志序列,您应该能够使用前瞻作为时间戳来查找序列的结尾。
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
。出于好奇,您是否考虑过使用Scanner的findWithinHorizon方法?在我看来它可以为你节省很多工作。
答案 1 :(得分:1)
如果我正确理解您的问题,您希望使用正则表达式拆分文件,但不能使用Java的内置Split()方法。在这种情况下,只需编写自己的Split()方法。
迭代所有正则表达式匹配。对于第一场比赛,存储比赛的时间戳和结束位置。对于后续匹配,请在前一个匹配的存储结束位置和当前匹配的起始位置之间取文本,并将其与上一个匹配相关联。然后存储当前匹配的时间戳和结束位置。在循环之后,在最后一个匹配的存储结束位置和文件末尾之间取文本,并将其与最后一个匹配相关联。
使用仅匹配时间戳并使用一些过程代码来获取时间戳之间的文本的正则表达式(远)比尝试提供与时间戳匹配的正则表达式以及直到下一个的所有内容更有效时间戳。
答案 2 :(得分:0)
我的代码中没有看到任何正则表达式,但这里有一个提示:
通过defailt,正则表达式中的点.
匹配除换行之外的所有内容。如果您希望它与新行匹配,则需要Pattern.DOTALL
作为Pattern.compile(str, flags)
的参数
匹配新行的另一种方法是使用与\s
匹配的预定义组[\t\n\x0B\f\r]