Hallo zusammen,
Ich habe mal wieder ein Anliegen
Ich habe eine Textdatei wo z.B "hallo" drin steht. Dank euch und dem Internet ist es mir ohne Probleme möglich nach einem String in der Datei zu suchen. Das Wort "hallo" wird in der Datei mit einer Variablen verbunden welche sich nun aber nicht direkt in der gleichen Zeile befindet sondern z.B. zwei drüber. Die Variable soll das Programm dann finden. Gibt es Möglichkeiten python zu sagen das er zwei Zeilen drüber nach der Variablen suchen soll die immer gleich anfängt z.B. "AB" gefolgt von einer Zahl die zufällig ist?
In .txt Datei suchen
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Die erste Frage, die sich stellt ist, ob die Datei so "kompliziert" aufgebaut sein muss.
Als Antwort kann man Dir nur sagen, dass man eigentlich nie direkt auf Dateien operiert, sondern auf Datenstrukturen. Je besser man die Bytes aus der Datei in höher gelagerte Konzepte transformiert (das nennt man parsen), desto einfacher ist die spätere Verarbeitung.
Du kannst natürlich mit einem RegExp nach einer solchen Stelle suchen, aber direkt einfach ist das imho aus dem Bauch heraus nicht. Einfacher wäre es, wenn Du den Text in eine geeignete Struktur parst und dazu einen Mechanismus baust, die eine solche Struktur wieder in eine Datei schreiben kann. XML-Parser tun z.B. nichts anderes, ähnliche wie JSON usw.
So würde ich hier wohl vorgehen.
(Aber zuerst die erste Frage beantworten! Evtl. hat man dann dieses Problem gar nicht!)
Als Antwort kann man Dir nur sagen, dass man eigentlich nie direkt auf Dateien operiert, sondern auf Datenstrukturen. Je besser man die Bytes aus der Datei in höher gelagerte Konzepte transformiert (das nennt man parsen), desto einfacher ist die spätere Verarbeitung.
Du kannst natürlich mit einem RegExp nach einer solchen Stelle suchen, aber direkt einfach ist das imho aus dem Bauch heraus nicht. Einfacher wäre es, wenn Du den Text in eine geeignete Struktur parst und dazu einen Mechanismus baust, die eine solche Struktur wieder in eine Datei schreiben kann. XML-Parser tun z.B. nichts anderes, ähnliche wie JSON usw.
So würde ich hier wohl vorgehen.
(Aber zuerst die erste Frage beantworten! Evtl. hat man dann dieses Problem gar nicht!)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
assert encoding_kapiert
danke für deine schnelle Antwort.
Die Datei ist kompliziert und verändern geht leider nicht. Grundlegend kann man aber sagen, wenn ich nach einem Wert in der Datei suche z.B. "test" das ein paar Zeilen weiter oben die dazugehörige Variable erscheint die anfangs immer gleich ist, z.B. 'S_A_' und sofort dahinter dann eine Zahl ist die sich je nach dem welchen Wert ich suche ändert.
Beispiel: Ich suche nach "test" und die dazugehörige Variable ist 'S_A_1' (Quasi die nächste "'S_A_" drüber).
Meine Idee war, ich suche test und das Programm geht solange weiter nach oben bis 'S_A_ kommt und packt dann nur die Ziffer dabei.
Die Datei ist kompliziert und verändern geht leider nicht. Grundlegend kann man aber sagen, wenn ich nach einem Wert in der Datei suche z.B. "test" das ein paar Zeilen weiter oben die dazugehörige Variable erscheint die anfangs immer gleich ist, z.B. 'S_A_' und sofort dahinter dann eine Zahl ist die sich je nach dem welchen Wert ich suche ändert.
Beispiel: Ich suche nach "test" und die dazugehörige Variable ist 'S_A_1' (Quasi die nächste "'S_A_" drüber).
Meine Idee war, ich suche test und das Programm geht solange weiter nach oben bis 'S_A_ kommt und packt dann nur die Ziffer dabei.
Hyperion hat es schon kurz angeschnitten, aber du bist nicht weiter darauf eingegangen: Wie sieht denn die Struktur der Datei aus? Irgend ein strukturiertes Format ist doch wahrscheinlich gegeben. Da wäre es einfacher, wenn du die Daten zunächst parst, in vernünftige Datenstrukturen umsetzt und darauf dann die Suche durchführst.
Das Leben ist wie ein Tennisball.
Warum liest du nicht einfach vorwärts, merkst dir jeweils das letzte "S_A_..." und verwendest es wenn dann später dein Suchbegriff kommt?Eisi hat geschrieben:Beispiel: Ich suche nach "test" und die dazugehörige Variable ist 'S_A_1' (Quasi die nächste "'S_A_" drüber).
Meine Idee war, ich suche test und das Programm geht solange weiter nach oben bis 'S_A_ kommt und packt dann nur die Ziffer dabei.
Ich würde nicht versuchen, in den Zeilen hin und her zu springen. Sobald Du auf ein Muster, das einem Namen entspricht ('S_A_') stößt, handelt es sich bei den Werten bis zum nächsten Namenstreffer ja wohl um den Bereich, in dem sich der gesuchte Wert ('test') befindet. Und so weiter...Eisi hat geschrieben:Meine Idee war, ich suche test und das Programm geht solange weiter nach oben bis 'S_A_ kommt und packt dann nur die Ziffer dabei.
mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit )
Es kommt nicht Automatisch nach jedem S_A_ der Suchbegriff. Er wird noch anderweitig verwendet. Selbst wenn ich die S_A_'s kenne wäre es noch schwerer den Wert dafür zu finden weil er nur mit einem " ' " anfängt und das ist in dieser Datei bei anderen (für mich) uninteressanten Daten öfter der Fall. Der Suchbegriff ist ja eine Ziffernfolge eingefasst in " ' " z.B. '12346' deswegen kann man Ihn leicht finden. Man muss dann nur noch gucken Welche ist das letzte S_A_/me hat geschrieben:Warum liest du nicht einfach vorwärts, merkst dir jeweils das letzte "S_A_..." und verwendest es wenn dann später dein Suchbegriff kommt?Eisi hat geschrieben:Beispiel: Ich suche nach "test" und die dazugehörige Variable ist 'S_A_1' (Quasi die nächste "'S_A_" drüber).
Meine Idee war, ich suche test und das Programm geht solange weiter nach oben bis 'S_A_ kommt und packt dann nur die Ziffer dabei.
@Eisi: Irgendwie scheint mir Dein Gegenargument keines zu sein. Du sollst ja nicht jedes 'S_A_' *verwenden* sondern dir nur immer das zuletzt gesehene *merken*. Und wenn dann der Suchbegriff kommt, brauchst Du nicht mehr rückwärts nach dem letzten 'S_A_' suchen, sondern Du hast Dir das letzte ja gemerkt und kannst es *dann* verwenden.
Also so ganz grob das Prinzip:
Code: Alles auswählen
def find(lines, needle):
previous_sa = None
for line in lines:
if line.startswith('S_A_'):
previous_sa = line
elif needle in line and previous_sa is not None:
yield previous_sa # hier eventuell ``return``...
# previous_sa = None # ...oder das hier zusätzlich.
Danke Blackjack für die Codehilfe. Als ich heute Nacht (mal wieder) über das erstellen des Programms gegrübelt habe kamen mir noch einige Ideen, die mich dann dazu bewegten nochmal alle verfügbaren .txt daten die damit zu tun haben mir anzuschauen. Es ist mir aufgefallen das es, wie ich jedenfalls denke, noch eine Datei gibt, die mir viel einfacher meine daten zur verfügung stellt. Die Datei besteht zum größten Teil aus einer immer gleichen Struktur.
[' 123456-1234' ' 1949' 614 0 1 [ 3000 2300][ -569336 798500 27000][ -61700 49100 18000][3 0 109 79 1][ 547 16797 13269] 'V13']
Ich suche nach 123456-1234 und er soll mir 3 0 109 79 1 am besten jede Zahl in einer Variablen abspeichern. Da 123456-1234 öfter vorkommt, interessiert mich nur das erste mal. Alles danach ist dann erstmal uninteressant. Wie kann man das in etwa verwirklichen?
Ich habe gerade gesehen das der Abstand immer gleich ist, egal welche zahlen zwischen den [ ] stehen. die [] sind immer gleich weit entfernt und wurden bei kürzeren zahlen mit leerzeichen gefüllt. vielleicht kann man damit arbeiten?
[' 123456-1234' ' 1949' 614 0 1 [ 3000 2300][ -569336 798500 27000][ -61700 49100 18000][3 0 109 79 1][ 547 16797 13269] 'V13']
Ich suche nach 123456-1234 und er soll mir 3 0 109 79 1 am besten jede Zahl in einer Variablen abspeichern. Da 123456-1234 öfter vorkommt, interessiert mich nur das erste mal. Alles danach ist dann erstmal uninteressant. Wie kann man das in etwa verwirklichen?
Ich habe gerade gesehen das der Abstand immer gleich ist, egal welche zahlen zwischen den [ ] stehen. die [] sind immer gleich weit entfernt und wurden bei kürzeren zahlen mit leerzeichen gefüllt. vielleicht kann man damit arbeiten?
Code: Alles auswählen
Import os
File = open(pfad, 'r')
Filetext = File.readline() ##falls du uir eine zeile (das heißt keine "enters") hast
Brackets = Filetext.split('][') ##das gibt dir die zahlen in den klammern in einer liste
for i in range(0, len(Brackets)-1):
Brackets[i] = Brackets[i].split(" ") ##gibt dir eine liste [(3000,2300),(-569336,798500,27000),...]
##Damit kannst du dann machen was du willst
##must sie aber vorher umwandeln, da sie string sind
Apostrophes = Filetext.split("'") ##gibt dir die nummern zwischen den anführungszeichen '
for i in range(len(Apostrophes)-1, 0, -1): ##zählt von hinten deine liste runter-->nur das letzte
##(also für dich erste) zählt
if Apostrophes[i] == "123456-1234":
Index = i
##index ist die stelle in der 123456-1234 das erste mal auftritt
0x4c65742773206d616b652073757265207468617420686973746f7279206e6576657220666f726765747320746865206e616d6520656e746572707269736521
@Kamik423: An deinem Code ist eigentlich in jeder Zeile etwas verkehrt. Zunächst das "Import" in der ersten Zeile, was wohl eindeutig ein "import" sein sollte. Hinzu kommt, dass das os-Modul später nirgends verwendet wird. Anschließend öffnest du die Datei, ohne dass diese irgendwo regulär wieder geschlossen wird, geschweige denn in einem Fehlerfall. Zum Öffnen von Dateien sollte daher das with-Statement verwendet werden.
Dann verstoßen deine Namen gegen jede übliche Namenskonvention von Python, auch passt die Schreibweise zu keiner anderen Sprache. Schau dir dazu mal den Styleguide an. Auch deine Namen sind nichtssagend gewählt. "File" ist total generisch, "Filetext" könnte auch einfach text, data oder content heißen, das Präfix ist total überflüssug. "Brackets" ist mindestens irreführend gewählt, da stecken ja gerade keine Klammern drin.
``for i in range(len(x))`` ist in Python ein Anti-Pattern. Wenn range in Verbindung mit len verwendet wird, dann ist das in der Regel falsch. Man kann direkt über Listen iterieren und muss nicht den Umweg über Indizes gehen. Wenn man doch mal den Index braucht, dann verwendet man dazu die enumerate-Funktion. Auch ist die Angabe der 0 als erster Parameter bei range überflüssig. Selbiges gilt auch für die zweite for-Schleife.
Auch in "Apostrophes" stecken wieder keine Apostrophe drinen, sondern Zahlen als Strings. Dabei fällt natürlich auch auf, dass der dazugehörige Kommentar fehlerhaft ist. Nummern sind etwas anderes als Zahlen.
Auch ist dein Programm fehlerhaft, falls es keinen Match gibt. Wird später im Programm "Index" verwendet, so wird ein NameError geworfen, da es nie definiert wurde. Ganz abgesehen davon bricht dein Programm zusammen, falls sich irgendwo Hochkommas im Fließtext befinden, dann funktioniert dein "Parsen" nicht mehr. Gleiches gilt, wenn die Strings stattdessen in Doppelten Anführungszeichen sind. Um ein vernünftiges Parsen kommt man nicht herum. Wenn deine Implementierung mal funktioniert, dann ist das eher reine Glücksache.
Dann verstoßen deine Namen gegen jede übliche Namenskonvention von Python, auch passt die Schreibweise zu keiner anderen Sprache. Schau dir dazu mal den Styleguide an. Auch deine Namen sind nichtssagend gewählt. "File" ist total generisch, "Filetext" könnte auch einfach text, data oder content heißen, das Präfix ist total überflüssug. "Brackets" ist mindestens irreführend gewählt, da stecken ja gerade keine Klammern drin.
``for i in range(len(x))`` ist in Python ein Anti-Pattern. Wenn range in Verbindung mit len verwendet wird, dann ist das in der Regel falsch. Man kann direkt über Listen iterieren und muss nicht den Umweg über Indizes gehen. Wenn man doch mal den Index braucht, dann verwendet man dazu die enumerate-Funktion. Auch ist die Angabe der 0 als erster Parameter bei range überflüssig. Selbiges gilt auch für die zweite for-Schleife.
Auch in "Apostrophes" stecken wieder keine Apostrophe drinen, sondern Zahlen als Strings. Dabei fällt natürlich auch auf, dass der dazugehörige Kommentar fehlerhaft ist. Nummern sind etwas anderes als Zahlen.
Auch ist dein Programm fehlerhaft, falls es keinen Match gibt. Wird später im Programm "Index" verwendet, so wird ein NameError geworfen, da es nie definiert wurde. Ganz abgesehen davon bricht dein Programm zusammen, falls sich irgendwo Hochkommas im Fließtext befinden, dann funktioniert dein "Parsen" nicht mehr. Gleiches gilt, wenn die Strings stattdessen in Doppelten Anführungszeichen sind. Um ein vernünftiges Parsen kommt man nicht herum. Wenn deine Implementierung mal funktioniert, dann ist das eher reine Glücksache.
Das Leben ist wie ein Tennisball.
Entschuldigung, ich habe das mit meinem ipad geschrieben, das autokapitalisiert, d.h. Setzt einen Großbuchstaben am zeilenanfang. Import ist überflüssig, außer du benutzt os um den Pfad anzugeben. Schließen habe ich vergessen, entschuldigungEyDu hat geschrieben:@Kamik423: An deinem Code ist eigentlich in jeder Zeile etwas verkehrt. Zunächst das "Import" in der ersten Zeile, was wohl eindeutig ein "import" sein sollte. Hinzu kommt, dass das os-Modul später nirgends verwendet wird. Anschließend öffnest du die Datei, ohne dass diese irgendwo regulär wieder geschlossen wird, geschweige denn in einem Fehlerfall. Zum Öffnen von Dateien sollte daher das with-Statement verwendet werden.
Ja, die Großbuchstaben wurden autogesetzt, und ich habe sie nicht geändert. Entschuldigung. Auch meine Namensgebung war nicht wirklich überdacht.EyDu hat geschrieben:Dann verstoßen deine Namen gegen jede übliche Namenskonvention von Python, auch passt die Schreibweise zu keiner anderen Sprache. Schau dir dazu mal den Styleguide an. Auch deine Namen sind nichtssagend gewählt. "File" ist total generisch, "Filetext" könnte auch einfach text, data oder content heißen, das Präfix ist total überflüssug. "Brackets" ist mindestens irreführend gewählt, da stecken ja gerade keine Klammern drin.
Brackets: an den klammern gesplitted.
Ich benutzte len() um mit Nummern zu iterieren um Indizes angeben zu können, um Bracket[index] auf einen wert setzten zu können. Ich kannte die enumerate funktion nicht. Auch benutze ich" in range" nicht sehr oft, und habe daher das mit der 0 vergessen.EyDu hat geschrieben:``for i in range(len(x))`` ist in Python ein Anti-Pattern. Wenn range in Verbindung mit len verwendet wird, dann ist das in der Regel falsch. Man kann direkt über Listen iterieren und muss nicht den Umweg über Indizes gehen. Wenn man doch mal den Index braucht, dann verwendet man dazu die enumerate-Funktion. Auch ist die Angabe der 0 als erster Parameter bei range überflüssig. Selbiges gilt auch für die zweite for-Schleife.
Apodtrophes: selbes wie oben.EyDu hat geschrieben:Auch in "Apostrophes" stecken wieder keine Apostrophe drinen, sondern Zahlen als Strings. Dabei fällt natürlich auch auf, dass der dazugehörige Kommentar fehlerhaft ist. Nummern sind etwas anderes als Zahlen.
Was ist der unterschied?
Yupp, ich habe vergessen index zu definieren. Parsen mit hochkommas funktioniert für mich...EyDu hat geschrieben:Auch ist dein Programm fehlerhaft, falls es keinen Match gibt. Wird später im Programm "Index" verwendet, so wird ein NameError geworfen, da es nie definiert wurde. Ganz abgesehen davon bricht dein Programm zusammen, falls sich irgendwo Hochkommas im Fließtext befinden, dann funktioniert dein "Parsen" nicht mehr. Gleiches gilt, wenn die Strings stattdessen in Doppelten Anführungszeichen sind. Um ein vernünftiges Parsen kommt man nicht herum. Wenn deine Implementierung mal funktioniert, dann ist das eher reine Glücksache.
Ich entschuldige mich nocheinmal für mein fehlerhaftes programm. Ich wollte nur helfen...
Danke fürs aufzeigen meiner fehler
0x4c65742773206d616b652073757265207468617420686973746f7279206e6576657220666f726765747320746865206e616d6520656e746572707269736521
@Eisi: Man könnte sich selbst etwas schreiben, oder zumindest nachvollziehen ob die Lösung die man übernehmen möchte, tatsächlich das Problem auf eine Art löst die robust genug ist.
Vielleicht bin ich aber auch nur zu sehr Perfektionist. Ich würde versuchen ob man das Datenformat nicht parsen kann, statt da auf Textebene Daten zu extrahieren. Sieht ja irgendwie nach etwas Lisp oder Scheme ähnlichen aus, nur mit eckigen Klammern statt runden.
Vielleicht bin ich aber auch nur zu sehr Perfektionist. Ich würde versuchen ob man das Datenformat nicht parsen kann, statt da auf Textebene Daten zu extrahieren. Sieht ja irgendwie nach etwas Lisp oder Scheme ähnlichen aus, nur mit eckigen Klammern statt runden.