Seite 1 von 1
String mit line.split() "von hinten" einlesen
Verfasst: Montag 31. März 2008, 16:52
von matlev
Hallo liebe Forumsteilnehmer,
ich habe ein kleines Problem mit Python. Ich lese eine Datei zeilenweise ein und speichere deren Inhalt in mehreren Variablen, die ich dann entsprechend in eine DB einbaue:
Code: Alles auswählen
for line in file(myDBfile, "r"):
try:
[id, A, B, C, D, E, D1, D2] = line.split('\t')
....
Bei A bis E handelt es sich hierbei um Strings, D1 und D2 sind Datumseinträge.
Es handelt sich um sehr viele Einträge, und ab und an kriege ich eine Fehlermeldung (ValueError: Too many values to unpack). Ich habe herausgefunden, dass es daran liegt, dass String C dummerweise teilweise (wenn auch recht selten) selbst einen "\t" enthält.
Da ich mich eigentlich nur für A, B und E interessiere, dachte ich mir, dass es auch ausreichen würde, wenn ich die Einträge "von hinten" aufspalte, um an String E heranzukommen (in etwa so: [rest, E, D1, D2] = ???). Aber ich weiß leider nicht, wie man das anstellen kann. Könnte mir einer von euch vielleicht netterweise helfen?
Vielen Dank und viele Grüße!
Verfasst: Montag 31. März 2008, 17:04
von helduel
Verfasst: Montag 31. März 2008, 17:05
von EyDu
Dann greif doch einfach über die Indizes drauf zu:
Code: Alles auswählen
lines = line.split()
A = lines[0]
B = lines[1]
E = lines[-3]
Verfasst: Montag 31. März 2008, 18:17
von matlev
Ähmm, ich habe das Gefühl, die Antwort war zu einfach, als dass die Frage es wert war, gestellt zu werden.
Vielen Dank jedenfalls, das hat wunderbar funktioniert und sehr geholfen!
Erkennen, ob Eintrag im Zeitformat ist
Verfasst: Dienstag 15. April 2008, 15:11
von matlev
Ich hätte doch nochmals ne kurze Frage zu diesem Thema. Wie ich bereits im ersten Posting geschrieben habe, handelt es sich bei den Datensätzen D1 und D2 um Zeiteinträge. Diese liegen im folgenden Format vor:
YYYY-MM-DD HH:MM:SS (z.B. 2008-04-15 16:10:00)
Da String C in der Mitte auch beliebige Zeilensprünge beinhalten kann, und ich an A, B und E rankommen möchte, würde ich halt immer von vorne A und B lesen und von hinten E. Dazu müsste ich aber überprüfen, ob es sich bei dem letzten Eintrag in einer Zeile um ein String im Zeitformat (wie oben beschrieben) handelt. Also so etwas wie:
lines = line.split()
isTime(lines[-1])
Gibt es so eine Methode in Python? Ich konnte nichts genaues finden bisher. Oder wie würde man das über Pattern Matching machen? Ich bräuchte dann auch so etwas wie (isLong() oder isInt() für den ersten Eintrag "id" (lines[0]).
Verfasst: Dienstag 15. April 2008, 16:34
von matlev
Falls es irgend jemand interessieren sollte, ich habe es nun so gelöst:
Code: Alles auswählen
while (1):
try:
lastField = lines[-1]
time.strptime(lastField, "%Y-%m-%d %H:%M:%S\n")
lines = line.split('\t')
break
except Exception:
line = f.next()
lines = line.split('\t')
line_count + 1
Zur Erklärung: Wenn das Format nicht übereinstimmt, dann bewirkt die Zeile
time.strptime(lastField, "%Y-%m-%d %H:%M:%S\n")
eine Exception. In dieser wird die nächste Zeile eingelesen und wieder geschaut, ob das Format im letzten Feld stimmt. Dies wird so lange gemacht, bis das Format das richtige ist.
Re: Erkennen, ob Eintrag im Zeitformat ist
Verfasst: Mittwoch 16. April 2008, 07:56
von Rebecca
matlev hat geschrieben:Da String C in der Mitte auch beliebige Zeilensprünge beinhalten kann
Ist der String denn in Delimiter eingefasst (Gaensefuesschen oder so)? Das csv-Modul kann naemlich mit solchen Strings gut umgehen und stoert sich nicht an Zeilenumbruechen. Dann haettest du das Datum immer in der gleichen Spalte.
Verfasst: Mittwoch 16. April 2008, 09:15
von matlev
Na ja, das ist ja das Problem. Die Delimiter der Text-Datei, die ich in eine Datenbank einlesen möchte, sind Tabs (\t). Aber im mittleren String (C) kommen auch Tabs vor. Das ist bescheuert gespeichert, aber nun mal das was ich habe und daher muss ich probieren, es trotzdem korrekt einzulesen.
Mit dem Code, welchen ich vorher beschrieben habe, funktioniert es aber - soweit ich es bisher getestet habe - ganz gut.
Verfasst: Mittwoch 16. April 2008, 10:20
von Rebecca
Nur nochmal zur Verdeutlichung: Das csv-Modul kommt problemlos mit sowas klar:
Code: Alles auswählen
111\t222\t"hallo\twelt"\t333
111\t222\t"hallo
welt"\t333
111\t222\t"hallo "bla" welt"\t333
Es hat kein Problem mit Delimitern im String, solange der String halt nochmal eigene Delimter hat (z.B. Gaensefuesschen).