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

时间:2016-04-13 00:02:38

标签: java parsing templates template-engine

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

*** 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 个答案:

答案 0 :(得分: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")));

答案 1 :(得分:1)

&#34;简单&#34;多行正则表达式?

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

答案 2 :(得分:-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
    }
}