2012-08-08 46 views
0

我已經檢查並使用了各種示例,看起來我的問題比我所能找到的要複雜一些。我需要做的是搜索一個特定的字符串,然後刪除下面的行並保持刪除行直到找到另一個字符串。因此,一個例子是以下幾點:刪除match1之後只匹配到匹配2

a 
b 
color [ 
0 0 0, 
1 1 1, 
3 3 3, 
] #color 
y 
z 

這裏,"color ["是MATCH1和"] #color"是MATCH2。那麼需要的是以下幾點:

a 
b 
color [ 
] #color 
y 
z 
+0

這將有助於確定哪些是「MATCH1」和「MATCH2」,也爲您的顯示輸入一些相應的輸出。還有其他任何約束(也可以通過輸入/輸出對來顯示)。 – Levon 2012-08-09 13:16:53

回答

2

這個「簡單易用」的代碼示例會讓你開始..你可以根據需要調整它。請注意,它會逐行處理文件,因此可以處理任何大小的文件。

start_marker = 'startdel' 
end_marker = 'enddel' 

with open('data.txt') as inf: 
    ignoreLines = False 
    for line in inf: 
     if start_marker in line: 
      print line, 
      ignoreLines = True 
     if end_marker in line: 
      ignoreLines = False    
     if not ignoreLines: 
      print line, 

它採用startdelenddel爲「標記」的開始和結束數據的忽略。

更新

基於評論的請求修改後的代碼,這將現在包括/打印包含「標誌」的行。

鑑於這種輸入數據(來自@drewk借用):

Beginning of the file... 
stuff 
startdel 
    delete this line 
    delete this line also 
enddel 
stuff as well 
the rest of the file... 

它產生:

Beginning of the file... 
stuff 
startdel 
enddel 
stuff as well 
the rest of the file... 
+0

這工作太棒了,但我需要保持搜索線'尋找這條線'和'直到找到這條線'。該代碼當前也刪除這些行。這是一個簡單的修改嗎? – 2012-08-08 01:06:47

+0

@ScottRichardson我更新了代碼,給它一個旋轉,看看它是否符合你的要求。 – Levon 2012-08-08 01:10:16

+0

嗨Levon,我嘗試了新的代碼,對我來說,它會打印'enddel'兩行。 – 2012-08-08 17:10:22

1

您可以通過使用nongreedy *有一個正則表達式做到這一點。例如,假設你想同時保留"look for this line""until this line is found"線,並丟棄只在字裏行間,你可以這樣做:

>>> my_regex = re.compile("(look for this line)"+ 
...      ".*?"+ # match as few chars as possible 
...      "(until this line is found)", 
...      re.DOTALL) 
>>> new_str = my_regex.sub("\1\2", old_str) 

的幾個注意事項:

  • re.DOTALL標誌告訴Python 「」可以匹配換行符 - 默認情況下,它匹配除換行符以外的任何字符
  • 圓括號定義了「編號匹配組」,稍後當我說「\ 1 \ 2」時確保我們不會丟棄第一行和最後一行。如果你確實想放棄其中的一個或兩個,那麼只要擺脫1和/或2。例如,保留第一個但不是最後一個使用my_regex.sub("\1", old_str);或擺脫都使用my_regex.sub("", old_str)

爲了進一步的說明,請參閱:http://docs.python.org/library/re.html或搜索你喜歡的搜索引擎「非貪婪正則表達式」。

+0

嗨,愛德華,這個工作很完美,非常感謝!雖然我在模型測試文件中試過這個,但是直到明天我才能在實際的文件上嘗試它。事實證明,我將使用它的文件將會非常大(> 10萬行),並且將會有多達20個塊需要刪除。所以我的問題是這個代碼對於包含很多行的文件是最有效的,並且這個代碼是否會執行這個操作直到找到eof?再次感謝你。 – 2012-08-08 19:55:15

+0

這將取代所有的事件。但是,如果你的文件非常大,那麼這可能不是最好的方法,因爲你需要讀入整個文件,處理它,然後寫出結果。所以你可能想要採用更像Levon所建議的方法。 (在現代系統中,將100k行文件加載到內存中並非沒有道理,但它當然不是最有效的方法。) – 2012-08-09 00:34:19

1

這工作:

s="""Beginning of the file... 
stuff 
look for this line 
    delete this line 
    delete this line also 
until this line is found 
stuff as well 
the rest of the file... """ 

import re 

print re.sub(r'(^look for this line$).*?(^until this line is found$)', 
      r'\1\n\2',s,count=1,flags=re.DOTALL | re.MULTILINE) 

打印:

Beginning of the file... 
stuff 
look for this line 
until this line is found 
stuff as well 
the rest of the file... 

您還可以使用單片要做到這一點:

mStart='look for this line' 
mStop='until this line is found' 
li=s.split('\n') 
print '\n'.join(li[0:li.index(mStart)+1]+li[li.index(mStop):]) 

相同的輸出。

我喜歡re這個(是一個Perl傢伙在心臟...)

+0

非常感謝大家! – 2012-08-08 01:27:56