2012-03-19 59 views
4

有沒有辦法將re.findall或更好的re.finditer功能應用到流(即文件句柄是否可以打開)?findall/finditer在流中?

請注意,假設要匹配的模式完全包含在一行輸入內(即允許多行模式),我是而不是。我也不是假設最大匹配長度。

確實,在這個普遍性水平上,可以指定一個正則表達式,它要求正則表達式引擎可以訪問整個字符串(例如r'(?sm).*'),當然這意味着必須閱讀整個文件存入內存,但我現在不關心這種最糟糕的情況。畢竟,完全有可能編寫多行匹配的正則表達式,其將而不是要求將整個文件讀入內存。

是否有可能通過編譯的正則表達式訪問底層自動機(或內部使用的任何內部函數),爲其提供一串字符?

謝謝!

編輯:添加關於多行模式和匹配長度的說明,以迴應蒂姆Pietzcker和rplnt的答案。

+0

感謝您的編輯 - 我已經更新了我的答案。 – 2012-03-20 08:48:48

回答

3

這是可能的,如果你知道正則表達式匹配永遠不會跨越換行符。

然後,你可以簡單地做

for line in file: 
    result = re.finditer(regex, line) 
    # do something... 

如果比賽可以擴展到多行,你需要閱讀整個文件到內存中。否則,你會如何知道你的比賽是否已經完成,或者如果前面的某些內容不可能讓比賽變得不可能,或者如果比賽只是因爲文件讀取不夠而失敗?

編輯:

理論上有可能做到這一點。正則表達式引擎必須檢查在匹配嘗試期間的任何時候它是否到達流的當前讀取部分的末尾,如果是,請繼續閱讀(可能直到EOF)。但是Python引擎不會這樣做。

編輯2:

我已經採取了看看Python的STDLIB的re.py及其相關模塊。一個正則表達式對象的實際生成,包括其.match()方法和其他方法在C擴展中完成。因此,除非您直接編輯C源代碼並構建自己的Python版本,否則無法訪問和修改它以處理流。

2

這將是可能的實現正則表達式已知的最大長度。不是+/*或者你知道最大重複次數的那個。如果你知道這一點,你可以通過塊讀取文件並匹配,得到結果。你也可以在重疊塊上運行正則表達式,而不是覆蓋正則表達式匹配但是在字符串末尾停止的情況。

一些僞(蟒蛇)代碼:

overlap_tail = '' 
matched = {} 
for chunk in file.stream(chunk_size): 
    # calculate chunk_start 
    for result in finditer(match, overlap_tail+chunk): 
     if not chunk_start + result.start() in matched: 
      yield result 
      matched[chunk_start + result.start()] = result 
    # delete old results from dict 
    overlap_tail = chunk[-max_re_len:] 

只是一個想法,但我希望你明白我想要的目的。您需要考慮該文件(流)可能會結束以及其他一些情況。但我認爲可以這樣做(如果正則表達式的長度是有限的(已知))。