2016-07-19 5 views
1

Ich habe unter zwei Zeile des Protokolls, wo ich separate regulären Ausdruck für die Suche nach jedem von ihnen haben möchte. Es ist kein Problem, auf der zweiten Protokollzeile auszulösen. Aber ich habe Probleme beim Ausdruck für die erste Zeile. Der Name Reset Reason test ist nur ein Beispiel für den Test, die Anzahl der Wörter darin kann variieren, daher kann ich hier keine spezifischeren Muster definieren, dann nur .*.Negative Lookahead Assertion in Python

12.07.2016 13:54:20 SCR_OUTPUT: #### TC_0006 Reset Reason test 
12.07.2016 13:54:20 SCR_OUTPUT: #### TC_0006 Reset Reason test done. 

Ich habe regulären Ausdruck im Allgemeinen tun das, was ich will es tun:

([0-9:. ]*) SCR_OUTPUT: #### (TC_[a-fA-F0-9]{4,5}[:0-9]{0,4}) .*[ ](?!done\.$) 

Und ich habe zwei Fälle, die ich zu differenzieren wollen: ich basierend auf dem Beispiel hier gegeben. https://docs.python.org/3/howto/regex.html#lookahead-assertions

Alles funktioniert gut, wenn es so endet: (natürlich muss ich meine Test-Strings ändern)

[.](?!done$) 

Wenn ich es versuchen, etwas zu sein, das zu mir passt mehr zB: (mein done. hat am Ende dot)

[.](?!done\.$) 

Dann wird es seltsam. Eine andere Anpassung. done. sollte mit Leerzeichen gefolgt werden und nicht mit Punkt und das Ergebnis wird verrückt. Jede Zeile gibt positive Ergebnisse.

[.](?!done\.$) 

Ich habe das auf pythex.org getestet. Unter diesem Link finden Sie die neueste Version meines Experiments.

Wer weiß, wo ich einen Fehler habe? Ist es irgendwie möglich, in einem solchen Fall auszulösen? Vielleicht sollte ich es in zwei Schritten tun?

+0

Möchten Sie die Übereinstimmung fehlschlagen, sobald eine Zeile/ein String mit 'done.' endet? ['^ ([0-9:.] *). * SCR_OUTPUT: #### (TC_ [a-fA-F0-9] {4,5} [: 0-9] {0,4}) (?!. * done \. $). * '] (https://regex101.com/r/nI7eQ2/1)? –

+0

Oder ['^ (?!. * Done \. $) ([0-9.] + \ S + [\ d:] +) \ s + SCR_OUTPUT: \ s * #### \ s * (TC_ \ w +). * '] (https://regex101.com/r/nI7eQ2/2) (was ist schneller)? –

+0

Genau. Immer wenn eine Zeile mit "fertig" ist. gegeben ist, sollte es darauf scheitern. – user2362824

Antwort

1

Wenn Sie Linien mit done. am Ende ausschließen möchten passenden, müssen Sie eine negative Vorschau verwenden, und besser verankert am Anfang der Zeile:

^(?!.* done\.$)([0-9.]+\s+[\d:]+)\s+SCR_OUTPUT:\s*####\s*(TC_\w+).* 
^^^^^^^^^^^^^^ 

Siehe regex demo (Sie erinnern sich die verwenden re.M Flag zu machen ^ passen Sie den Anfang der Zeile anstelle der Zeichenfolge starten, wenn Sie mehrzeilige Zeichenfolge Eingabe).

Hinweis Ich habe das Regex-Muster für die von Ihnen bereitgestellten Strings verbessert (der ursprüngliche Teil ([0-9.]+\s+[\d:]+)\s+ reduziert das Backtracking erheblich, Sie sollten etwas Ähnliches verwenden, wenn dieses genaue Muster nicht mit allen Ihren Daten übereinstimmt).

Auf jeden Fall ist der Kern der Umgebung der Look-Ahead-(?!.* done\.$), die sofort das Spiel ausfällt, sobald es überprüft, ob es einen Raum + done. am Ende (done.) nach 0+ andere Zeichen als eine neue Zeile, so viele wie möglich (.*).

+0

Vielen Dank. Genau das ist der Job. Diese Lektion habe ich in keinem Beispiel gesehen. – user2362824

+0

Im Falle des Datums eine Zeit habe ich das kürzeste mögliche Muster, nur um es kurz zu machen. Dieser Teil war in meinem Problem jedenfalls unwichtig. Aber danke für die Beratung, ich werde darüber nachdenken. – user2362824

+0

Ja, Sie können '[0-9 .:] +' verwenden, um es "kürzer" zu machen, aber die '. *' Vermeiden, dass 'SCR_OUTPUT' ein Overkill war. Denken Sie auch daran, dass "kürzer" nicht "effizienter" bedeutet und fast nie "genauer" in der Regex-Welt bedeutet. –