2013-03-08 52 views
1

嗨,我正在處理一個600Mb文件。我寫了下面的代碼。我正在做的是,在<dest>標記之間的數據中搜索關鍵字,如果存在,則將城市標記添加到<dest>標記。它適用於小數據集,但是當我在大文件上運行程序時,它正在拋出MEMORY ERROR。我想我得到這個錯誤,當我在if condition使用return語句可以任何人請讓我知道如何解決這個問題?函數返回語句期間Python內存錯誤

import re 

def casp (tx): 
    def tbcnv(st): 
     ct = '' 
     prt = re.compile(r"(?i)(Slip Copy,.*?\))", re.DOTALL|re.M) 
     val = re.search(prt, st) 
     try: 
      ct = val.group(1) 
      if re.search(r"(?i)alaska", ct): 
       jval = "Alaska" 
       print jval 
       if jval: 
        prt = re.compile(r"(?i)(.*?<dest.*?>)", re.DOTALL|re.M) 
        vl = re.sub(prt, "\\1\n" + "<city>" + jval + "</city>" + "\n" ,st) 
        return vl 
       else: 
        return st 
      else: 
       return st 
     except: 
      print "Not available" 
      return st 

    pt = re.compile("(?i)(<dest.*?</dest>)", re.DOTALL|re.M) 
    t = re.sub(pt, lambda m: tbcnv(m.group(1)), tx) 
    return t 

with open('input.txt', 'r') as content_file: 
    content = content_file.read() 
    pt = re.compile(r"(?i)<Lrlevel level='3'>(.*?)</Lrlevel>", re.DOTALL|re.M) 
    content = re.sub(pt,lambda m: "<Lrlevel level='3'>" + casp(m.group(1) + "</Lrlevel>"), content) 

with open('out.txt', 'w') as out_file: 
    out_file.write(content) 
+0

我猜測在600M文件上運行正則表達式可能會導致內存錯誤... – akaIDIOT 2013-03-08 09:13:44

+3

逐行讀取文件,read()會將整個文件一次寫入內存,導致這個錯誤。 – 2013-03-08 09:13:59

+0

@AshwiniChaudhary我需要捕獲兩行之間的多行標籤之間的日期。 – 2013-03-08 09:15:36

回答

2

如果你只是expect之前刪除return聲明,然後由re.sub()內置字符串要小得多。

我得到的內存使用量是文件大小的3倍,這意味着如果您沒有(超過)2GB,會出現MemoryError錯誤。這在這裏是合理的 - 或者至少我可以猜測爲什麼。這就是re.sub()的工作原理。

這意味着您正在使用錯誤的工具,正如上面的註釋中所述。你應該使用一個完整的xml處理工具,比如lxml,或者如果你想堅持使用正則表達式,找一種永遠不需要內存中整個字符串的方法;或者至少永遠不要打電話給re.sub()(例如,只有tx變量包含一個大字符串,這是輸入;而你在循環中做pt.search(tx, startpos),定位要改變的位置,並且一片一片地寫入tx)。