2016-04-13 7 views
2

Ich möchte meinen Protokolldateiparser vereinfachen und komplexe reguläre Ausdrücke durch eine Vorlagenengine ersetzen. Die Idee besteht darin, den Prozess einer Template-Engine umzukehren und als Eingabe die Template-Beschreibung und eine gültige Ergebnisdatei anzugeben. Die Multi-line-Log-Dateien wie folgt aussehen:Verwenden Sie Vorlagen-Engine zum Analysieren mehrzeiliger Protokolldatei in Java

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

* Device: XKK-255141 

Alle von ihnen haben die gleiche Struktur und kann in einer Pseudo-Template-Sprache beschrieben werden:

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

* Device: XKK-{{integer}} 

Gibt es eine Template-Engine, die eine parst Protokolldatei, sucht die Struktur in der Vorlagendatei und gibt den Inhalt in einer HashMap/List/Object zurück?

Hinweis: Ich bin mir bewusst, dass ich ein einfaches DSL in ANTLR schreiben könnte. Die Idee hier ist jedoch, das Parsen zu vereinfachen und zu akzeptieren, dass nur einfache mehrzeilige Protokolldateien ohne Rekursion unterstützt werden.

Antwort

1

Ich bin mir nicht bewusst einen bestehenden Template-Engine, die dies nicht (sie in der Regel um die andere Art und Weise arbeiten, Vorlagen mit Daten füllen).

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

Verbrauch::

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

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

Stefan, danke für den Code! Dies ist eine ziemlich schlaue Art, das Problem zu lösen. –

-1

Es gibt viele von ihnen.

Auschecken YAML und JSON. Sie sind wirklich einfach zu bedienen.

Das einzige Problem ist, dass Sie das Format jeder Vorlage Sprache folgen müssen.

Hier ist, wie Ihre Datei in diesen Sprachen geschrieben würde.

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

Ich möchte die Eingabedateien analysieren und nicht das Format von ihnen ändern. –

1

Wie wärs mit einer "einfachen" Multi-Line Regex

Warum so etwas wie diesem nicht verwenden?

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

Es ist ein bisschen chaotisch wegen der umgekehrten Schrägstrich zu schreiben und Wildcard entkommt, aber es funktioniert der Trick ... (und oben auf dieser Logik könnte man leicht einen String Transformation schreiben, die Ihre Vorlage passende String Karte würde zu einer Regex, wenn Sie wollen).

Verwandte Themen