2017-10-28 1 views
1

Ich benutze Python Version 3.6 auf einem Windows-Rechner. Ich lese in einer Textdatei mit open() und readlines(). Nach dem Einlesen der Textdateizeilen möchte ich bestimmte Zeilen in eine neue Textdatei schreiben, aber bestimmte Zeilenbereiche ausschließen. Ich kenne die Zeilennummern der auszuschließenden Zeilen nicht. Die Textdateien sind massiv und der Bereich der auszuschließenden Zeilen variiert zwischen den Textdateien, die ich gerade lese. Es gibt bekannte Schlüsselwörter, nach denen ich suchen kann, um den Anfang und das Ende des auszuschließenden Bereichs aus der Textdatei zu finden, in die ich schreiben möchte.Python 3+, Textdatei einlesen und in neue Datei schreiben, ohne Zeilenumfang

Ich habe überall online gesucht, aber ich kann nicht scheinen, eine elegante Lösung zu finden, die funktioniert. Das Folgende ist ein Beispiel für das, was ich erreichen möchte.

a 
b 
BEGIN 
c 
d 
e 
END 
f 
g 
h 
i 
j 
BEGIN 
k 
l 
m 
n 
o 
p 
q 
END 
r 
s 
t 
u 
v 
BEGIN 
w 
x 
y 
END 
z 

Zusammenfassend möchte ich das oben in Python lesen. Schreiben Sie anschließend in eine neue Datei, schließen Sie jedoch alle Zeilen aus, die bei BEGIN beginnen und bei END-Schlüsselwörtern anhalten.

Die neue Datei sollte folgende Angaben enthalten:

a 
b 
f 
g 
h 
i 
j 
r 
s 
t 
u 
v 
z 

Antwort

1

Wenn die Textdateien massiv sind, wie Sie sagen, sollten Sie vermeiden, readlines() zu verwenden, da dies das gesamte Ding im Speicher lädt. Lesen Sie stattdessen zeilenweise und verwenden Sie eine Statusvariable, um zu steuern, ob Sie sich in einem Block befinden, in dem die Ausgabe unterdrückt werden soll. So etwas wie,

import re 

begin_re = re.compile("^BEGIN.*$") 
end_re = re.compile("^END.*$") 
should_write = True 

with open("input.txt") as input_fh: 
    with open("output.txt", "w", encoding="UTF-8") as output_fh: 
     for line in input_fh: 
      # Strip off whitespace: we'll add our own newline 
      # in the print statement 
      line = line.strip() 

      if begin_re.match(line): 
       should_write = False 
      if should_write: 
       print(line, file=output_fh) 
      if end_re.match(line): 
       should_write = True 
+0

Ich endete damit. Ich brauche keinen regulären Ausdruck in meiner speziellen Situation, also werde ich das Modul re nicht verwenden. Außerdem habe ich 'print (line, file = output_fh)' in output_fh.write (line) geändert, da die print-Anweisung folgende Warnung ausgelöst hat: Erwarteter Typ 'Optional [IO [str]]', stattdessen 'TextIOWrapper [str]' . Vielen Dank für Ihre Unterstützung! – jmm5351

1

Sie können die folgende Regex verwenden, dies zu erreichen:

regex = r"(\bBEGIN\b([\w\n]*?)\bEND\b\n)" 

Live-Demo here

können Sie entsprechen den oben regex und dann durch eine leere Zeichenfolge ersetzen ('')

Here's ein Arbeitsbeispiel in Python für das gleiche.

CODE

result = re.sub(regex, '', test_str, 0) # test_str is your file's content 
>>> print(result) 
>>> 
a 
b 
f 
g 
h 
i 
j 
r 
s 
t 
u 
v 
z 
+0

Was passiert, wenn es String wie "BEGIN123" trifft? – ailin

+0

aktualisiert, danke –

0

Haben Sie so etwas wie dies versucht:

with open("<readfile>") as read_file: 
    with open("<savefile>", "w") as write_file: 
     currently_skipping = False 
     for line in read_file: 
      if line == "BEGIN": 
       currently_skipping = True 
      else if line == "END": 
       currently_skipping = False 

      if currently_skipping: 
       continue 

      write_file.write(line) 

, die im Grunde tun sollten, was Sie tun müssen. Im Grunde lesen Sie nicht alles über "readlines" in den Speicher, sondern gehen Sie mehr Zeile für Zeile - das sollte auch für Speicher schlanker sein.

Verwandte Themen