2016-05-13 5 views
0

Wenn Sie dies auf einer aus drei Buchstaben bestehenden Zeichenfolge ausführen, werden einfach 5 Übereinstimmungen zurückgegeben. Coliru.So rufen Sie eine Hierarchie von Übereinstimmungen aus einer Regex ab

Stattdessen möchte ich zwei "toplevel" Übereinstimmungen abrufen, wobei die erste Übereinstimmung zwei Unterübereinstimmungen enthält. Ich würde gerne in der Lage sein, sie in jede Tiefe zu nisten und einen passenden Baum von Streichhölzern zu finden.

Es scheint, als hätte Boost mit "nested matches" so etwas. Ist das richtig? Und kann ich das in C++ 11 ohne Boost machen?

Extra: ein etwas weniger trivial Spielzeug Beispiel, wo dies sinnvoll sein könnte:

((,[0-9]+)+)((,[a-z])+) 

Dies würde eine Reihe von Zahlen übereinstimmen, gefolgt von einer Reihe von Wörtern, die alle durch Komma getrennt. Ich möchte die Zahlenspiele von den Wortspielen trennen, anstatt eine flache Reihe von Spielen zu haben.

+0

Wofür? Was glaubst du, könntest du mit solch einer Einrichtung machen, auf die du nicht verzichten kannst? –

+0

@IgorTandetnik, ich habe gerade ein etwas komplexeres Beispiel hinzugefügt, um dies zu motivieren –

+3

Sie scheinen zu glauben, dass Sie ein separates Spiel für jede Wiederholung der Gruppe bekommen würden. So funktioniert 'std :: regex' nicht. Sie erhalten genau so viele Übereinstimmungen wie im normalen Ausdruck öffnende Parens plus eins. Mit anderen Worten, die Anzahl der zurückgegebenen Übereinstimmungen wird durch die Syntax des Ausdrucks festgelegt und hängt nicht von der Eingabe ab, für die eine Übereinstimmung gefunden wird. –

Antwort

0

Die Sache über Regex ist, dass sie nicht rekursive Descent-Parser sind. Aber Sie können eine Kombination aus Regex und C++ (oder jeder anderen Sprache) verwenden.

Nur ein Hinweis, es gibt einige Probleme mit dieser Regex ist:

((,[0-9]+)+)((,[a-z])+) 

Um das erste Element nicht zu verpassen passenden, muss die Liste mit , starten. Das andere Problem besteht darin, dass Sie auch nur 1-Buchstaben-Wörter in Kleinbuchstaben lesen.

Der Einfachheit halber werde ich das erste Problem lösen, indem ich annahm, dass Sie jede Zeichenfolge mit , voranstellen. Das zweite Problem kann durch Änderung der regex gelöst werden:

((,[0-9]+)+)((,[a-zA-Z]+)+) 

Beachten Sie, dass dies nicht mehr als eine Reihe von Zahlen durch eine Reihe von Worten gefolgt erfassen. Dazu müssen Sie in einer Schleife suchen, wie die Kommentare sagten.

Jetzt, da das behoben ist, kann ich erklären, wie Sie das erreichen können, was Sie wollen.

Alle numerischen Übereinstimmungen sind in matches[1]. Alle alphabetischen Übereinstimmungen sind in matches[3].

Sie können jedes einzelne Element in der numerischen Liste durch Aufteilen auf , erhalten. Das gleiche gilt für die alphabetische Liste.

+0

In diesem Fall wird 'Übereinstimmungen [2]' das gleiche wie 'Übereinstimmungen [1]'? Und 'passt [4]' das gleiche wie 'stimmt mit [5]' überein? –

+0

@AaronMcDaid Nein, 'Übereinstimmungen [2]' wird nur die letzte Iteration enthalten, die übereinstimmte. Gleiches gilt für 'Übereinstimmungen [4]'. Aber es gibt keine Übereinstimmungen [5] (zählen Sie die Anzahl der öffnenden Klammern). – Laurel

+0

Sorry, ich meinte '3' statt' 5'! Jedenfalls verstehe ich jetzt Danke. Die Tatsache, dass das letzte Match gewonnen wird, ist möglicherweise sehr nützlich - es würde einem automatischen Schema erlauben, die einzelnen Matches wiederholt zu entfernen. –

Verwandte Themen