mikrocontroller.net

Forum: PC-Programmierung Regex zum Verzweifeln.


Autor: SimonU (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich probiere jetzt seit 5 Stunden herum und komme einfach nicht weiter. 
Programmiersprache ist Python.

Es gibt Logdateien mit unbestimmer Anzahl an Einträgen.

1300105811    Datei7    test0    test10   
1300107321    Datei7    test1    test9   
1300108129    Datei7    test2    test8   
1300107162    Datei7    test3    test7   
1300105515    Datei7    test4    test6   
1300106386    Datei7    test5    test5   
1300106818    Datei7    test6    test4   
1300106542    Datei7    test7    test3   
1300106770    Datei7    test8    test2   
1300105745    Datei7    test9    test1

Die sehen alle in etwa so aus. Grundsätzlich ist der Aufbau so, dass
es verschiedene Felder gibt, die durch \t getrennt sind. Wenn ein neuer 
Eintrag kommt, erkennt man das an \t\n. Es ist möglich, dass ein Eintrag 
sich über mehrere Zeilen erstreckt. Das heißt, dass in einem Eintrag in 
einem Feld ein \n vorkommen kann. Das kann jedoch niemals am Anfang 
eines Feldes geschehen.

So, mein Problem ist jetzt das Auslesen dieser Datei.

Meine Versuche reichen von
compiled_regex = re.compile(r"(([^\t]+?\t)+?\n)+?", re.MULTILINE)  

über
compiled_regex = re.compile(r"((\S+?\t)+?\n)+?", re.MULTILINE)  

usw...

Keine der Versionen funktioniert wie erwartet! Ich erhalte immer nur ein 
Feld zurück, außer ich mache das so:
compiled_regex = re.compile(r"((\S+?\t)(\S+?\t)\n)+?", re.MULTILINE)    

Dann erhalte ich zwei Felder.

Die Anzahl der Felder ist aber dynamisch! Ich suche also einen Regex, 
mit dem ich ALLE Felder (zw. 1 und 50) in ALLEN Einträgen ermitteln 
kann.

ich komme jedenfalls nicht mehr weiter.

Habt ihr eine Idee?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mach es in zwei Schritten:
1. Datei an \t\n in Zeilen aufsplitten
2. jede Zeile an \t in Spalten aufsplitten

Beispiel in Ruby (kannst du sicher einfach in Python umsetzen):
s = "1\t2\t3\t\n1\t2\t\n"
zeilen  = s.split(/\t\n/)
felder = zeilen.map do |zeile|
  zeile.split(/\t/)
end

puts felder.inspect

=> [["1", "2", "3"], ["1", "2"]]

Autor: SimonU (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das wäre natürlich möglich. Da ich aber sehr sehr viele Logeinträge 
habe, muss ich auf Performance achten (Dateien sind teils über 10MB 
groß).

Ist es komplett unmöglich, das in einem Regex zu machen?

Autor: Andreas Schwarz (andreas) (Admin) Benutzerseite Flattr this
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso meinst du dass das mit einer Regex schneller gehen wird? Bei 
verschachtelten Ausdrücken ist nur die Wahrscheinlichkeit höher dass du 
dir einen Speicher- und Rechenzeitfresser mit exponentieller Komplexität 
baust.

Und spielt Rechenzeit überhaupt eine Rolle? 10 MB ist doch nichts.

Autor: Peter II (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SimonU schrieb:
> Dateien sind teils über 10MB groß
wahnsinn, und da machst du dir gedanken? Bei mir fängt groß zur zeit bei 
1GB an.

Autor: SimonU (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sind jeweils ca. 50 Dateien pro Skriptdurchlauf. Also 500MB könnten 
da schon zusammenkommen.

Ich werde es jetzt so lösen (2 Schritte), bis ich eine Lösung mit nur 
einem regulären Ausdruck habe. Das war auch die Vorgabe an das Programm 
(vom Chef)

Autor: SimonU (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
läuft

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
SimonU schrieb:
> bis ich eine Lösung mit nur
> einem regulären Ausdruck habe
Oh man... was soll das bringen? nur weil der "Chef" das sagt?

SimonU schrieb:
> ich probiere jetzt seit 5 Stunden herum
Stattdessen nochmal ein paar Stunden "rumprobieren"... wiviele Millarden 
Jahre soll den das Skript sich im EInsatz befinde das es die (noch 
nichtmal nachgewiesene) Geschwindigkeitssteigerung wieder reinholt die 
man durch solche "Optimierungen" verbrät?
Gerade bei großen Dateien kann es sich lohne die Datei Zeilenweise 
einzulesen, da hierdurch nicht erst die ganze Datei in den Speicher 
geladen werden muss.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.