2017-09-28 1 views
0

Rückkehr Ich habe eine Zeichenfolge wie folgt:Python regulärer Ausdruck nicht alle Gruppen

<hello<world<1 \< 2>, die "hello", "world", "1 < 2" eine Liste mit drei Saiten darstellt. Ich möchte, dass mein regulärer Ausdruck mit ("hello", "world", "1 \< 2") übereinstimmt. (Ich entferne die Backslashes später in der Auswertung). Ich verwende den folgenden regulären Ausdruck, den Text zu entsprechen:

r"(?:<((?:[^<>]|\\.)*))+>" 

So wie ich es verstehe, es passt zumindest eine (< mit einer beliebigen Anzahl von nicht <> oder \anything, nachdem es) und dann eine Schließung > , aber die Ergebnisse deuten nicht darauf hin. Mit re.match(..., ...).groups(), erhalte ich folgend:

>>> import re 
>>> re.match(r"(?:<((?:[^<>]|\\.)*))+>", r"<hello<world<1 \< 2>").groups() 
<<< (' 2',) 
>>> re.match(r"(?:<((?:[^<>]|\\.)*))+>", r"<hello<world<1 \< 2>").group(0) 
<<< '<hello<world<1 \\< 2>' 

Was ist verwirrend, dass group(0) ist nicht einmal in groups(), und es scheint, dass der Rest des Teils ist nicht in group(...). Ist etwas falsch mit meinem regulären Ausdruck oder Ansatz, und wie sollte ich es beheben?

Um klar zu sein, ich baue einen Lexer für eine Golf-Sprache mit Regex, so dass es durch etwas wie ein Char-by-Char-Lexer zu ersetzen wäre unbequem, da ich bereits den regulären Ausdruck Lexer und die meisten Ausdrücke haben Konfiguration. Ich frage mich, ob eine reine Regex-Lösung möglich ist.

+0

Wie wäre es nur Aufspaltung von '<'? 're.split (r" (? ") – Psidom

+0

@Psidom Funktioniert nicht für das Backslashed' <'... obwohl ich versuchen könnte, ein non zu verwenden -capturing match für etwas Nicht-Backslash davor. Ich werde es versuchen, danke! – HyperNeutrino

+0

@Psidom Hey, das funktioniert wirklich schön. Vielen Dank! Können Sie eine Antwort posten, damit ich Ihren Ansatz auffrischen kann? – HyperNeutrino

Antwort

1

Sie können dies versuchen:

s = "<hello<world<1 \< 2>" 
import re 
l = [i for i in re.split("\<(?!\s\d)|\>", s) if i] 

Ausgang:

['hello', 'world', '1 \\< 2'] 
+0

Das kleine Problem mit dieser Antwort ist, dass "<<>" '[" "," "]' geben sollte. Anstatt "wenn ich" würde ich wahrscheinlich einfach 're.split (" ... ", s) [1: -1]'. – HyperNeutrino

+0

@HyperNeutrino Ich bin mir nicht sicher, ob ich den Kontext dieses Problems verstehe. Könnten Sie die Zeichenfolge, die '' enthält, veröffentlichen und was ist Ihre gewünschte Ausgabe? – Ajax1234

+0

Nein, wie Ihr Ansatz alle leeren Strings (die am Anfang und am Ende) entfernen wird, aber wenn ich 's =" <<> "' setze, erwarte ich 'l = [" "," "]' wohingegen Ihre Antwort '' ergeben würde [] 'weil leere Strings entfernt werden. – HyperNeutrino

Verwandte Themen