2017-10-28 164 views
1

我在Windows機器上使用Python版本3.6。我正在用文本文件open()readlines()閱讀。在閱讀文本文件行後,我想將某些行寫入新的文本文件,但排除了某些範圍的行。我不知道要排除的行的行號。文本文件很大,要排除的行的範圍在我正在閱讀的文本文件中有所不同。我可以搜索已知的關鍵字來查找要從要寫入的文本文件中排除的範圍的開始和結束。Python 3+,讀取文本文件並寫入新文件排除行範圍

我到處都在網上搜索,但我似乎無法找到一個優雅的解決方案。以下是我想要實現的一個例子。

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 

總之,我想將上面的代碼讀入Python。之後,寫入一個新文件,但是排除從BEGIN開始並在END關鍵字處停止的所有行。

新的文件應包含以下內容:

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

回答

1

如果文本文件非常龐大,就像您說的那樣,您會希望避免使用readlines(),因爲這會將整個內容加載到內存中。相反,逐行閱讀並使用狀態變量來控制您是否在輸出應被抑制的塊中。東西有點像,

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

我最終使用了這個。我不需要在特定情況下使用正則表達式,所以我不打算使用re模塊。此外,由於print語句引發了以下警告,我將'print(line,file = output_fh)'更改爲output_fh.write(line):預期類型'Optional [IO [str]]',改爲'TextIOWrapper [str]' 。 謝謝大家的支持! – jmm5351

1

您可以使用下面的正則表達式來實現這一目標:

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

現場演示here

可以搭配使用上述正則表達式然後替換爲空字符串(''

Here's在Python中的一個工作示例相同。

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

如果遇到字符串「BEGIN123」會怎麼樣? – ailin

+0

已更新,謝謝 –

0

你有沒有嘗試過這樣的事情:

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) 

這應該基本上你需要做什麼。 基本上不會通過'readlines'將所有內容都讀入內存,但可以逐行讀取更多內容 - 也應該更加精簡內存。