Ich bin mir nicht sicher, ob ich hier richtig bin, aber ich versuche es einfach mal. Ich habe mal eine Frage zu Regex, ich muss einen Apachelog nach bestimmten Vorgaben analysieren lassen, dabei kann ich eine solche Beispielzeile aus der Datei: 172.16.11.12 - - [26/May/2013:14:06:05 +0200] \"GET /navleiste/d_szut_navleiste.gif HTTP/1.1\" 200 1776 mit Hilfe von (r"^(.*?) (.*?) (.*?) \[(.*?)\] \"(.*?) (.*?) (.*?)\" (.*?) (.*?)$") zumindest schonmal abdecken, jedoch weiß ich nicht genau, wie ich die einzelnen "Gruppen" in anderer Reihenfolge bzw. alleine abrufen kann. Möglicherweise mache etwas Grundlegend falsch oder übersehe etwas.
MfG.
Taadu
Regex-Gruppen
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
die Gruppen sind durchnummeriert und mit der `group()` Methode kannst du drauf zugreifen. Beispiel (Python 3.5):
Mit `groups()` siehst du alle Capture-Gruppen:
[codebox=pycon file=Unbenannt.txt]>>> m.groups()
('172.16.11.12', '-', '-', '26/May/2013:14:06:05 +0200', 'GET', '/navleiste/d_szut_navleiste.gif', 'HTTP/1.1', '200', '1776')
>>>
[/code]
Gruß, noisefloor
die Gruppen sind durchnummeriert und mit der `group()` Methode kannst du drauf zugreifen. Beispiel (Python 3.5):
Code: Alles auswählen
>>> my_string = '172.16.11.12 - - [26/May/2013:14:06:05 +0200] \"GET /navleiste/d_szut_navleiste.gif HTTP/1.1\" 200 1776'
>>> import re
>>> regex = r'^(.*?) (.*?) (.*?) \[(.*?)\] \"(.*?) (.*?) (.*?)\" (.*?) (.*?)$'
>>> p = re.compile(regex)
>>> m = p.match(my_string)
>>> m.group()
'172.16.11.12 - - [26/May/2013:14:06:05 +0200] "GET /navleiste/d_szut_navleiste.gif HTTP/1.1" 200 1776'
>>> m.group(0)
'172.16.11.12 - - [26/May/2013:14:06:05 +0200] "GET /navleiste/d_szut_navleiste.gif HTTP/1.1" 200 1776'
>>> m.group(1)
'172.16.11.12'
>>> m.group(5)
'GET'
>>> m.group(6)
'/navleiste/d_szut_navleiste.gif'
>>>
[codebox=pycon file=Unbenannt.txt]>>> m.groups()
('172.16.11.12', '-', '-', '26/May/2013:14:06:05 +0200', 'GET', '/navleiste/d_szut_navleiste.gif', 'HTTP/1.1', '200', '1776')
>>>
[/code]
Gruß, noisefloor
Vielen Dank für die Antworten, sie haben mir sehr weitergeholfen, ich werde das sobald wie möglich ausprobieren.
Ich war gerade dabei einen Beitrag zu verfassen, in dem ich um ein Beispiel bitte und noch davor wurde eines bereitgestellt.
Ich war gerade dabei einen Beitrag zu verfassen, in dem ich um ein Beispiel bitte und noch davor wurde eines bereitgestellt.
Hier ein Bsp. für named groups:
Gruppen mit Namen sind einfach übersichtlicher.
Code: Alles auswählen
r = '^(?P<ip>[\d\.]*)[^\[]*(?P<datum>[^\]]*)[^\"]*\"(?P<befehl>[^ ]*) (?P<pfad>[^ ]*) (?P<protokol>[^\"]*)[^\d]*(?P<zahlen>.*)$'
Ich bin jetzt nach dem Beispiel von noisefloor vorgegangen und bekomme nun auch eine Ausgabe wie ich sie brauche bzw. haben möchte, jedoch habe ich jetzt das Problem, das ich am Ende eines Durchlaufs folgenden Fehler bekomme:
print((m.group()))
AttributeError: 'NoneType' object has no attribute 'group'
Ich verstehe jetzt nicht genau, wieso ich zwar die richtige Ausgabe bekomme wenn ich die jeweilige Gruppe ausgebe, aber ich trotzdem diese Meldung bekomme.
print((m.group()))
AttributeError: 'NoneType' object has no attribute 'group'
Ich verstehe jetzt nicht genau, wieso ich zwar die richtige Ausgabe bekomme wenn ich die jeweilige Gruppe ausgebe, aber ich trotzdem diese Meldung bekomme.
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
den Fehler kann ich so nicht nachvollziehen. Ich kann `m.group()` nicht nachvollziehen bzw. den Befehl beliebig oft aufrufen.
Was meinst mit
Gruß, noisefloor
den Fehler kann ich so nicht nachvollziehen. Ich kann `m.group()` nicht nachvollziehen bzw. den Befehl beliebig oft aufrufen.
Was meinst mit
? Bzw. welche Durchlauf meinst du? Benutzt du irgendwo einen Iterator?das ich am Ende eines Durchlaufs folgenden Fehler bekomme
Gruß, noisefloor
noisefloor hat geschrieben: Bzw. welche Durchlauf meinst du? Benutzt du irgendwo einen Iterator?
Gruß, noisefloor
So sehr kenne ich mich mit der Materie nicht aus, ich kann zu Veranschaulichung aber eine runtergebrochene Version meines Quelltextes Zeigen.
Code: Alles auswählen
import re
antwort = open("antwort.txt", "a")
Pfad = "c:/Users/talib/Desktop/apache.log"
try:
daten = open(Pfad)
except:
print("Dateizugriff nichterfolgreich")
exit(0)
for zeile in daten:
regex = (r"^(.*?) (.*?) (.*?) \[(.*?)\] \"(.*?) (.*?) (.*?)\" (.*?) (.*?)$")
p = re.compile(regex)
m = p.match(zeile)
print(m.group())
antwort.close()
Traceback (most recent call last):
File "C:/Users/talib/PycharmProjects/untitled1/16 test.py", line 18, in <module>
print(m.group())
AttributeError: 'NoneType' object has no attribute 'group'
Zuletzt geändert von Anonymous am Montag 15. Mai 2017, 11:36, insgesamt 3-mal geändert.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
Grund: Quelltext in Python-Codebox-Tags gesetzt.
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
teste doch mal vor dem `print`, ob `m ` überhaupt existiert:
Zum Code: nackte `try ... except` sind schlecht, weil du _alle_ Fehler abfängst. Wenn du z.B. einen SyntaxError im Code hättest, dann würde bei dir auch "Datenzugriff nicht erfolgreich" stehen was mindestens mal irreführend ist. Wenn fängt man gezielt bestimmte Fehler ab.
Wenn bei dir eine Exception geworfen würde, würde die Datei nicht geschlossen, weil die Zeile mit `antworten.close()` nie erreicht würde. Das müsste wenn noch in einen `finally` Block.
Zum Öffnen von Dateien nimmt man normalerweise das `with` Statement, weil sich Python dann darum kümmert, dass die Datei auch wieder geschlossen wird.
Gruß, noisefloor
teste doch mal vor dem `print`, ob `m ` überhaupt existiert:
Code: Alles auswählen
...
if m:
print(m.group())
Wenn bei dir eine Exception geworfen würde, würde die Datei nicht geschlossen, weil die Zeile mit `antworten.close()` nie erreicht würde. Das müsste wenn noch in einen `finally` Block.
Zum Öffnen von Dateien nimmt man normalerweise das `with` Statement, weil sich Python dann darum kümmert, dass die Datei auch wieder geschlossen wird.
Gruß, noisefloor
@Taadu: Noch eine Anmerkung zum Quelltext: Das `re.compile()` macht so keinen Sinn, denn wenn Du das gleiche Muster in jedem Schleifendurchlauf immer wieder in ein RegEx-Objekt übersetzt, könntest Du auch gleich `re.match()` verwenden.
Einbuchstabige Namen sind keine gute Idee. Ich rätsele immer noch was `p` eigentlich bedeuten soll.
`exit()` sollte man nur verwenden wenn es wirklich benötigt wird, was bei einer 0 als Argument eigentlich nie der Fall ist, denn das passiert auch ganz automatisch wenn das Programm am Ende angelangt ist. Und man kann Programme eigentlich immer so strukturieren, dass das Programmende mit dem ”natürlichen Ende” zusammenfällt. Ausnahme ist der Fall wo man explizit andere Werte als 0 als Rückgabecode an den aufrufenden Prozess übermitteln möchte. Ausserdem müsste man `exit()` aus dem `sys`-Modul importieren. Das es auch ohne geht ist ein undokumentiertes Implementierungsdetail von CPython.
Warum behandelst Du die Ausnahme *überhaupt*? Denn das Programm würde ja auch ohne die Behandlung bei einer Ausnahme abbrechen. Sogar mit mehr Informationen über das Problem was aufgetreten ist.
Einbuchstabige Namen sind keine gute Idee. Ich rätsele immer noch was `p` eigentlich bedeuten soll.
`exit()` sollte man nur verwenden wenn es wirklich benötigt wird, was bei einer 0 als Argument eigentlich nie der Fall ist, denn das passiert auch ganz automatisch wenn das Programm am Ende angelangt ist. Und man kann Programme eigentlich immer so strukturieren, dass das Programmende mit dem ”natürlichen Ende” zusammenfällt. Ausnahme ist der Fall wo man explizit andere Werte als 0 als Rückgabecode an den aufrufenden Prozess übermitteln möchte. Ausserdem müsste man `exit()` aus dem `sys`-Modul importieren. Das es auch ohne geht ist ein undokumentiertes Implementierungsdetail von CPython.
Warum behandelst Du die Ausnahme *überhaupt*? Denn das Programm würde ja auch ohne die Behandlung bei einer Ausnahme abbrechen. Sogar mit mehr Informationen über das Problem was aufgetreten ist.
- noisefloor
- User
- Beiträge: 4149
- Registriert: Mittwoch 17. Oktober 2007, 21:40
- Wohnort: WW
- Kontaktdaten:
Hallo,
Kannst du dir jetzt aussuchen, ob das meine Post besser macht oder das Howto schlechter
Gruß, noisefloor
Das ist natürlich korrekt - im gegebenen Fall sind die Variablennamen an das offizielle Python-Howto zur Regex angelehnt: https://docs.python.org/3.5/howto/regex ... egex-howtoEinbuchstabige Namen sind keine gute Idee. Ich rätsele immer noch was `p` eigentlich bedeuten soll.
Kannst du dir jetzt aussuchen, ob das meine Post besser macht oder das Howto schlechter

Gruß, noisefloor
@noisefloor: Bei Deinem Code kann man ja noch sagen das ist kein Quelltext sondern eine Livesitzung in einer Python-Shell. Das ist ja alles kurz und übersichtlich und da hat so etwas wie leicht zu tippen gegenüber nach Jahren und mehreren Überarbeitungen noch verständlich zu lesen, auch einen anderen Stellenwert. 

Ich würde beertonic da zustimmen. Insbesondere da wir ja jetzt auch wissen das dort durchaus Zeilen vorkommen die nicht dem Muster entsprechen, würde ich sicherstellen wollen das es nicht so leicht passieren kann, dass man Zeilen matcht die man gar nicht haben möchte weil das Suchmuster so/zu unscharf formuliert ist. Ausserdem würde ich „named groups“ mindestens für die Teilausdrücke verwenden, die für die Auswertung interessant sind. Das macht den Code verständlicher als irgendwelche magischen Indexzahlen.
Danke für die Hilfreichen Tipps, jedoch habe eine Frage, die nicht mehr viel mit Regex zu tun hat, ich frage mich gerade, ob es möglich ist eine Variable wie eine Textdatei zu beschreiben also vom Aufbau her. Ich habe nämlich das problem, das ich eine bestimmte Zeilenstruktur nur am Ende bzw. Anfang ausgeben will, also muss ich sie vorher irgendiwe zwischenspeichern (möglicherweise in einer Liste?), erst wollte ich mit Hilfe eines Zählers automatisch immer neue Variablen erstellen lassen, um diese dann am Ende in die Textdatei schreiben zu lassen, dann habe ich hier im Forum aber gelesen das dies vermieden werden sollte, vielleicht hat auch hier jemand einen Vorschlag für mich.
Mit einem solchen versuch
hat er "ausgabe" nur immer mit der neusten "Wert" überschrieben
Mit einem solchen versuch
Code: Alles auswählen
ausgabe = (zeile +zeile)
Nimm eine Liste
Wenn du Variablen bis zum nächsten Programmaufruf speichern willst kannst du das mit pickle machen, oder einfach in eine Datei schreiben.
http://www.python-kurs.eu/dateien.php
Code: Alles auswählen
liste.append(zeile+zeile)
http://www.python-kurs.eu/dateien.php
@Taadu: Sammel die Daten doch einfach in einer Liste. Oder schreibe sie vor bzw. nach den anderen Zeilen in die Textdatei.