2016-11-04 2 views
1

Wie passen Sie eine Wiederholungsgruppe innerhalb einer Wiederholungsgruppe?Regex: Get verschachtelte Wiederholungsgruppe

Zum Beispiel alle gültig Datensätze in einer Log-Datei bekommen:

---: 
TS : 150602000006S 
EC1: 02429.523 
EC2: 05604.110 
--- 
---: 
TS : 150603000006S 
---: 
TS : 150603000006S 
EP1: 3333.523 
--- 

Wie die folgenden Begegnungen:

[ 
    [ 
    ['TS ', '150602000006S'], 
    ['EC1', '02429.523'], 
    ['EC2', '05604.110'] 
    ], 
    [ 
    ['TS', '150603000006S'], 
    ['EP1', '3333.523'] 
    ] 
] 

die einzelnen Datensatz Eigenschaften Abrufen können mit (See on regex101) erfolgen:

([A-Z0-9 ]{3,3}): ([0-9SW]+)?([0-9\.SW]{3,})\n 

Allerdings Beim Platzieren von Regex in einer Datensatzgruppe (like seen here) werden die Eigenschaftsgruppen nicht mehr übereinstimmend angezeigt.

Wie wird das richtig gemacht?

+1

Wahrscheinlich nicht mit Regex ... – Mena

+0

@Mena Warum wäre das nicht möglich? – JasperJ

+0

Ich sage nicht, dass es kategorisch nicht möglich ist, aber im Allgemeinen sind reguläre Ausdrücke gut für die Analyse von Text nicht kontextuell zu einer bestimmten Grammatik (z. B. Regex gegen Markup ist im Allgemeinen eine sehr schlechte Idee). Wenn Sie verschachtelte Elemente und Regeln für die Verschachtelung haben, werden reguläre Ausdrücke sehr bald sehr schwerfällig. Angenommen, Sie finden den richtigen Weg, um Ihre hierarchischen Datensätze anzupassen, wird der Ausdruck selbst lang, wahrscheinlich unlesbar und sehr schwer zu pflegen sein. In der Regel möchten Sie hierfür einen eigenen Parser implementieren. – Mena

Antwort

1

Um dies zu erhalten, würde ich versuchen, dies in ein paar regulären Ausdrücken aufzuteilen.

Zuerst möchten Sie eine Art grundlegende Überprüfung durchführen, um sicherzustellen, dass die Daten in einem Format vorliegen, das Sie erwarten. Ich würde die Anzahl der Vorkommen jedes der folgenden Ausdrücke zählen. Wenn sie nicht übereinstimmen, gib einfach auf *.

---:\n 
---(\n|$) 

Sobald Sie wissen, diese gleich sind, möchten Sie wahrscheinlich die gesamte Zeichenfolge gegen ein Muster passen sie in einzelne Abschnitte zu brechen, zum Beispiel

---:\n.*?---(\n|$) 

dies ein Literal ---: durch eine Neue-Zeile, gefolgt von so wenig Text wie möglich folgte repräsentiert (*? faul), gefolgt von entweder einer Neuen-Zeile oder dem Ende der Schnur. Sie müssten dies mit dem s Einlinien-Flag ausführen.

Dies würde Ihnen drei Übereinstimmungen in Ihrer Beispielzeichenfolge geben. Sie könnten dann Ihr Muster bei jedem der resultierenden Übereinstimmungen ausführen.


* Aufgeben kann wie die einfache Möglichkeit, scheinen hier draußen, aber es ist schwierig, jede genaue Vermutungen über falsch formatierte Daten zu machen. In Anbetracht Ihrer früheren Beispiel haben wir zwei Möglichkeiten, wenn wir diese Daten normalisieren wollen, sowohl als Kommentare hinzugefügt:

---: 
TS : 150602000006S 
EC1: 02429.523 
EC2: 05604.110 
--- 
---: 
TS : 150603000006S 
     // Add a closing tag here? 
---: // Remove this opening tag? 
TS : 150603000006S 
EP1: 3333.523 
--- 

Was sind die Folgen, wenn wir nicht richtig erraten? Gibt es Vorteile bei Fehlern? Es hängt vollständig von Ihrer Anwendung ab.

+0

Ich stimme der Aufteilung der Regex in zwei Teile zu. Und dies passt zwar zu den einzelnen Datensätzen, aber es kümmert sich nicht um ungültige Datensätze [wie hier zu sehen] (https://regex101.com/r/Rlw2tn/1).Gibt es dafür eine Regex-Lösung? – JasperJ

+0

@JasperJ Ich habe meine Antwort geändert. Ich hoffe es hilft. – Michael