2012-12-17 50 views
4

我需要用正則表達式掃描一個300MB的文本文件。正則表達式搜索一個非常大的文件

  • 讀取整個文件並將其放入一個變量中會吃掉超過700MB的RAM,然後因「無法分配內存」錯誤而失敗。
  • 匹配可以是兩三行,所以我不能在循環中使用線到線步進。

有沒有懶惰的方法來做一個正則表達式的完整文件掃描而不讀入一個單獨的變量?

UPD

完成。現在你可以使用這個函數按塊讀取。 修改它以實現您的目標。

def prepare_session_hash(fname, regex_string, start=0) 
    @session_login_hash = {} 
    File.open(fname, 'rb') { |f| 
    fsize = f.size 
    bsize = fsize/8 
    if start > 0 
     f.seek(start) 
    end 

    overlap = 200 

    while true 
     if (f.tell() >= overlap) and (f.tell() < fsize) 
     f.seek(f.tell() - overlap) 
     end 
     buffer = f.read(bsize) 
     if buffer 
     buffer.scan(s) { |match| 
      @session_login_hash[match[0]] = match[1] 
     } 
     else 
     return @session_login_hash 
     end 
    end 
    } 
end 

回答

5
  1. 導線在塊中的文件,而不是由行,其中塊是通過經常出現的字符或圖案的出現次數創建的訂單,說「X」。
  2. 「X」是這樣的,它永遠不會在你的正則表達式中存在,即「X」是你的正則表達式永遠不會匹配字符串的地方。
  3. 在當前塊中匹配您的正則表達式,提取匹配並繼續下一個塊。

實施例:

This is string with multline numbers -2000 
2223434 
34356666 
444564646 
. These numbers can occur at 34345 
567567 places, and on 67 
87878 pages . The problem is to find a good 
way to extract these more than 100 
0 regexes without memory hogging. 

在本文中,假設所需的圖案是數字串例如/d+/s匹配位數多, 然後,而不是處理和加載整個文件,則可以選擇一個塊創建圖案,在這種情況下,請說完全停止.,並且只能讀取並處理至此模式,然後移至下一個塊。

CHUNK#1:

​​

CHUNK#2:

These numbers can occur at 34345 
567567 places, and on 67 
87878 pages 

等。

編輯: 添加@從註釋Ranty的建議,以及:

或僅僅是線的一定量的閱讀,說20.當你發現內 比賽,清理到了比賽結束,追加另外20行。 不需要計算頻繁出現的'X'。

+1

或者只是通過一定數量的行讀取,比如說20.當您找到匹配項時,清除匹配結束並追加另外20行。不需要計算頻繁發生的'X'。 – Ranty

+0

@Ranty很好的建議。 – DhruvPathak