Text zwischen zwei Strings isolieren

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
fiberkill
User
Beiträge: 10
Registriert: Dienstag 5. Februar 2013, 20:29

Hallo zusammen,

ich bin noch recht neu in der Python Programmierung und stehe gerade etwas auf dem Schlauch.
Ich möchte aus einer csv Datei einen Textblock isolieren, der zwischen zwei fest definierten Strings steht:
Beispiel csv: (vor dem "BEGIN 123456" und nach dem "END 123456" gibt es noch weitere Zeilen, welche mich aber nicht interessieren.
.....
BEGIN 123456
"60","23622","G",236,"G"
"60","236220","G",236,"G"
"60","237","J",108,"J"
"60","238","J",39,"J"
"60","2382","J",33,"J"
"60","23821","J",18,"J"
"60","238210","J",18,"J"
"60","23822","J",15,"J"
"60","238220","J",15,"J"
END 123456
....


Ich möchte den Textblock zwischen "BEGIN 123456" und "END 123456" in ein Dictionary einlesen und dieses dann weiter verarbeiten.
Ich kann die csv Datei einlesen und mit einem "for loop" durch die Zeilen iterieren, aber wie ich den Block zwischen den beiden Strings in ein dict bekomme ist mir nicht ganz klar.

Habt Ihr hierzu vielleicht einen Tipp für mich

Vielen dank im Voraus.

FK
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

Du willst alles vor der BEGIN-Zeile weglassen (dropwhile) und dann alles nehmen bis zur END-Zeile (takewhile):

Code: Alles auswählen

from itertools import dropwhile, takewhile

with open("datei.csv", newline="", encoding="utf8") as lines:
    lines = dropwhile(lambda l:not l.startswith('BEGIN'), lines)
    _ = next(lines) # drop BEGIN
    lines = takewhile(lambda l:not l.startswith('END'), lines)
    data = list(csv.reader(lines))
Wie aus den Daten ein Dictionary werden soll, ist mir aber unklar. Wie soll denn das Ergebnis aussehen?
dirk009
User
Beiträge: 27
Registriert: Donnerstag 3. Juni 2021, 21:49

Hallo Fiberkill,

hier zwei Ansätze das File zeilenweise zu lesen und den Block zu extrahieren (einmal als String und einmal als Liste):

Code: Alles auswählen

import csv

with open('data.csv', encoding="utf8") as csvfile:
    foundBegin = False
    reader = csv.reader(csvfile, delimiter=',')
    for row in reader:
        if 'BEGIN 123456' in row:
            foundBegin = True
            continue # skip printing
        if 'END 123456' in row:
            break 
        if foundBegin:
            print(row) # row ist eine Liste der Strings in einer Zeile
            
with open('data.csv', encoding="utf8") as file:
    foundBegin = False
    line = True
    while line:
        line = file.readline()
        if 'BEGIN 123456' in line:
            foundBegin = True
            continue # skip printing
        if 'END 123456' in line:
            break 
        if foundBegin:
            print(line, end='') # line ist eine Zeile als String
Ausgabe 1. Teil:

Code: Alles auswählen

['60', '23622', 'G', '236', 'G']
['60', '236220', 'G', '236', 'G']
['60', '237', 'J', '108', 'J']
['60', '238', 'J', '39', 'J']
['60', '2382', 'J', '33', 'J']
['60', '23821', 'J', '18', 'J']
['60', '238210', 'J', '18', 'J']
['60', '23822', 'J', '15', 'J']
['60', '238220', 'J', '15', 'J']
Ausgabe 2. Teil:

Code: Alles auswählen

"60","23622","G",236,"G"
"60","236220","G",236,"G"
"60","237","J",108,"J"
"60","238","J",39,"J"
"60","2382","J",33,"J"
"60","23821","J",18,"J"
"60","238210","J",18,"J"
"60","23822","J",15,"J"
"60","238220","J",15,"J"
Sirius3
User
Beiträge: 18216
Registriert: Sonntag 21. Oktober 2012, 17:20

@dirk009: Variablennamen schreibt man generell komplett klein: found_begin
Nur der Teil zwischen BEGIN und END sind csv-Blöcke, die ganze Datei als solches zu behandeln kann zu fehlerhaften Daten führen. csv-Dateien muß man immer mit newline="" öffnen.

Beim zweiten Code ist mir die while-Schleife unklar. Eine Variable sollte nur eine Bedeutung haben, `line` ist aber erst ein Boolean und dann plötzlich ein String. Das ist sehr verwirrend. Warum verwendest Du nicht einfach eine for-Schleife über `file`?
fiberkill
User
Beiträge: 10
Registriert: Dienstag 5. Februar 2013, 20:29

@all: Vielen Dank für Eure Hilfe.
Hab mein Problem Dank Eurer Beiträge lösen können.
Antworten