使用模板引擎解析 Java 中的多行日志文件

Use template engine to parse multi-line log file in Java

我想简化我的日志文件解析器并用模板引擎替换复杂的正则表达式。这个想法是反转模板引擎的过程,并将模板描述和有效结果文件作为输入。多行日志文件如下所示:

*** ID: X821 ***
- type: B5
- time-stamp: 20160202T01:11:01.2991

* Device: XKK-255141

它们都具有相同的结构并且可以用伪模板语言描述:

*** ID: {{string}} ***
- type: {{string}}
- time-stamp: {{date}}

* Device: XKK-{{integer}}

是否有解析日志文件的模板引擎,查找模板文件中的结构和 HashMap/List/Object 中的 returns 内容?

注: 我知道我可以在 ANTLR 中编写一个简单的 DSL。但是这里的想法是简化解析并接受只支持没有递归的基本多行日志文件。

有很多。

查看 YAML and JSON。它们真的很容易使用。

唯一的问题是,您必须遵循每种模板语言的格式。

以下是使用这些语言编写文件的方式。

YAML

-- YAML
ID : X821
type : B5
time-stamp : 2016-02-02 01:11:01.2991
Device :
 - XKK : 255141

JSON

{
    "__comment" : "JSON",
    "ID": "X821",
    "type": "B5",
    "time-stamp": 20160202T01:11:01.2991,
    "Device": {
        "XKK": 255141
    }
}

我不知道现有的模板引擎可以执行此操作(它们通常以相反的方式工作,用数据填充模板)。

为什么不用这样的东西:

class ReverseTemplateEngine {
   ArrayList<String> prefixes = new ArrayList();
   ArrayList<String> suffixes = new ArrayList();

   public ReverseTemplateEngine(String... templates) {
     for (String s: templates) {
       int cut = s.indexOf("$");
       suffixes.add(s.substring(0, cut));
       prefixes.add(s.substring(cut + 1);
     }
   }

   public List<String> parse(BufferedReader r) {
     ArrayList<String> result = new ArrayList<>();
     while (true) {
       String line = reader.readLine();
       for (int i = 0; i < prefixes.length; i++) {
         if (line.startsWith(prefixes.get(i)) 
             && line.endsWith(suffixes.get(i)) {
           result.add(line.substring(prefixes.get(i).length(),
                      line.length() - suffixes.get(i).length()));
           break;
         }
       }
     }
     return list;
   }
 }

用法:

ReverseTemplateEngine rte = new ReverseTemplateEngine(
   "*** ID: $ ***",
   "- type: $",
   "- time-stamp: $",
   "* Device: XKK-$");

List<String> result = rte.parse(new BufferedReader(
     new FileReader("yourfile.txt")));

"simple" 多行正则表达式怎么样?

String test = 
  "*** ID: X821 ***\n" + 
  "- type: B5\n" + 
  "- time-stamp: 20160202T01:11:01.2991";

java.util.regex.Pattern p = java.util.regex.Pattern.compile(
  "^\*\*\* ID: (\S+) \*\*\*\s+" + 
  "- type: (\S+)\s+" + 
  "- time-stamp: (\S+)", 
  java.util.regex.Pattern.MULTILINE);

java.util.regex.Matcher m = p.matcher(test);
if(m.find()) {
    System.out.println("ID = " + m.group(1));
    System.out.println("type = " + m.group(2));
    System.out.println("time = " + m.group(3));
}

由于反斜杠和通配符转义,写起来有点乱,但它确实起到了作用...(在此逻辑之上,您可以轻松编写一个字符串转换,将您的模板匹配字符串映射到正则表达式,如果你愿意的话)。