Ich möchte jede Zeile in meiner Protokolldatei verarbeiten und die IP
Adresse extrahieren , wenn die Zeile meinem Muster entspricht. Es gibt verschiedene Arten von Nachrichten, im folgenden Beispiel verwende ich p1 and
p2`.
Ich konnte die Datei Zeile für Zeile lesen und für jede Zeile mit jedem Muster übereinstimmen. Aber da es viel mehr Muster geben kann, möchte ich es so effizient wie möglich machen. Ich hatte gehofft, diese Muster zu einem Objekt zusammenzufassen und das Match nur einmal für jede Zeile durchzuführen:
import re
IP = r'(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})'
p1 = 'Registration from' + IP + '- Wrong password'
p2 = 'Call from' + IP + 'rejected because extension not found'
c = re.compile(r'(?:' + p1 + '|' + p2 + ')')
for line in sys.stdin:
match = re.search(c, line)
if match:
print(match['ip'])
aber der obige Code funktioniert nicht, er beschwert sich, dass ip
er zweimal verwendet wird.
Was ist der eleganteste Weg, um mein Ziel zu erreichen?
BEARBEITEN:
Ich habe meinen Code basierend auf der Antwort von @Dev Khadka geändert.
Aber ich habe immer noch Probleme damit, wie ich mit den vielen ip
Spielen richtig umgehen kann . Der folgende Code gibt alle IPs aus, die mit p1 übereinstimmen:
for line in sys.stdin:
match = c.search(line)
if match:
print(match['ip1'])
Einige Zeilen stimmen jedoch nicht überein p1
. Sie passen zusammen p2
. dh ich bekomme:
1.2.3.4
None
2.3.4.5
...
Wie finde ich die passende IP drucken, wenn ich nicht weiß , wheter es war p1
, p2
...? Ich möchte nur die IP. Es ist mir egal, zu welchem Muster es passt.
quelle
Antworten:
Sie können das hervorragende
regex
Modul installieren , das viele erweiterte Regex-Funktionen unterstützt, einschließlich Zweig-Reset-Gruppen , um genau das Problem zu lösen, das Sie in dieser Frage beschrieben haben. Verzweigungsrücksetzgruppen sind mit gekennzeichnet(?|...)
. Alle Erfassungsgruppen mit denselben Positionen oder Namen in unterschiedlichen alternativen Mustern innerhalb einer Gruppe zum Zurücksetzen von Zweigen verwenden dieselben Erfassungsgruppen für die Ausgabe.Beachten Sie, dass im folgenden Beispiel die übereinstimmende Erfassungsgruppe zur benannten Erfassungsgruppe wird, sodass Sie nicht mehrere Gruppen durchlaufen müssen, um nach einer nicht leeren Gruppe zu suchen:
Demo: https://repl.it/@blhsing/RegularEmbellishedBugs
quelle
Warum überprüfst du nicht, welcher Regex übereinstimmt?
oder so ähnlich wie:
oder auch
quelle
match[i]
in einer for-Schleife iterieren ?if match[name] is not None:
IndexError: no such group
name in match
stattdessen zu verwendenDas liegt daran, dass Sie denselben Gruppennamen für zwei Gruppen verwenden
Versuchen Sie dies, dies gibt die Gruppennamen ip1 und ip2
quelle
Benannte Erfassungsgruppen müssen unterschiedliche Namen haben. Da jedoch alle Erfassungsgruppen dasselbe Muster erfassen sollen, ist es in diesem Fall besser, keine benannten Erfassungsgruppen zu verwenden, sondern einfach reguläre Erfassungsgruppen zu verwenden und die Gruppen vom Übereinstimmungsobjekt aus zu durchlaufen So drucken Sie die erste Gruppe, die nicht leer ist:
Demo: https://repl.it/@blhsing/UnevenCheerfulLight
quelle