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

3
我希望简化我的日志文件解析器,并使用模板引擎替换复杂的正则表达式。这个想法是反转模板引擎的过程,并将模板描述和有效结果文件作为输入。多行日志文件如下:
*** 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中的内容?

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

3个回答

1

我不知道是否有现成的模板引擎可以实现这个功能(它们通常是使用数据填充模板)。

为什么不尝试使用像这样的东西:

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")));

Stefan,感谢分享代码!这是解决问题的一种非常聪明的方式。 - Sascha Vetter

1
如何使用“简单”的多行正则表达式?
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));
}

由于反斜杠和通配符转义,编写起来有点混乱,但它确实可以解决问题...(在此逻辑的基础上,您可以轻松编写一个字符串转换,将模板匹配字符串映射到正则表达式,如果您想要)。


-1

有很多种。

看看YAMLJSON。它们非常容易使用。

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

以下是在这些语言中编写文件的方式。

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
    }
}

1
我想解析输入文件,而不改变它们的格式。 - Sascha Vetter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接