2015-02-12 67 views
0

我正在研究一個叫做pydlp的小項目。它基本上是一組正則表達式簽名,將從文件對象中提取數據。而一個檢查提取的數據是否真的很有趣的函數。將數據推入正則表達式?

此代碼是我如何執行匹配。這遠非最佳,因爲我必須一遍又一遍地讀取文件。

for signature in signatures: 
match = signature.validate(signature.regex.match(fobj.read()))) 
if match: matches.append(match) 
fobj.seek(0) 

是否有執行多個正則表達式的方式相同的文件對象上的匹配,而僅讀取文件內容物一次。文件對象可以很大,所以我不能把它放在內存中。

編輯:

我想澄清一下,爲什麼我的意思是「推到數據正則表達式」。我認識到正則表達式與有限狀態機有相似之處。與其一次將整個數據傳遞給正則表達式引擎,是否有可能一次推送部分數據?

while True: 
data = fobj.read(1024) 
if data == "": break 
for signature in signatures: 
    match = signature.regex.push_and_match(data) 
if match: matches.append(match) 

編輯2: 刪除鏈接,我刪除從GitHub項目。

+0

只讀一次文件內容並循環簽名?這肯定比重新讀取文件更快,我不明白你爲什麼這樣做。 – nhahtdh 2015-02-12 08:02:05

+1

數據和正則表達式的性質是什麼?它是面向行的文本數據嗎?正則表達式是以單行的文本還是更大的單位進行操作的? – FMc 2015-02-12 08:05:28

+0

嗨@nhahtdh。我不喜歡我目前的做法。如果可以的話,我不希望讀取整個文件內容,而是將它的一部分推入正則表達式引擎,因爲它正在被讀取(n)。我一直在思考如何使用某種滑動窗口來實現這一目標的策略。但在我這樣做之前,我想看看是否有人可以提出更好的解決方案。 – 2015-02-12 08:06:32

回答

0

如果您不需要匹配對象但只匹配字符串,可以考慮使用re.findall()?如果文件太大,您可以按照您的建議對部分進行分片,但使用一些重疊部分,不要錯過任何正則表達式(如果您知道正則表達式的性質,也許可以找出多大的重疊應該是)。

1

標準的方式做這樣的文字處理有太大的文件讀入內存是通過線來遍歷文件行:

regexes = [ .... ] 

with open('large.file.txt') as fh: 
    for line in fh: 
     for rgx in regexes: 
      m = rgx.search(line) 
      if m: 
       # Do stuff. 

但這種方法假設你的正則表達式可以在單一的成功運營孤立的文本行。如果他們不能,也許有其他單位,你可以傳遞給正則表達式(例如,由空行分隔的段落)。換句話說,您可能需要進行一些預解析,以便在將文本發送到主正則表達式之前抓取有意義的文本部分。

with open('large.file.txt') as fh: 
    section = [] 
    for line in fh: 
     if line.strip(): 
      section.append(line) 
     else: 
      # We've hit the end of a section, so we 
      # should check it against our regexes. 
      process_section(''.join(section), regexes) 
      section = [] 

    # Don't forget the last one. 
    if section: 
     process_section('\n'.join(section), regexes) 

關於你的文字問題:「是否有執行多個正則表達式的方式,而僅讀取文件對象中的內容一旦同一個文件對象相匹配」。不,是的。沒有意義,Python正則表達式對字符串進行操作,而不是文件對象。但是,您可以在一個字符串上同時執行多個正則表達式搜索,只需使用替換。這裏有一個小例子:

patterns = 'aa bb cc'.split() 
big_regex = '|'.join(patterns) # Match this or that or that. 
m = big_regex.search(some_text) 

但是,這並不能真正解決你的問題,如果該文件是太大的記憶。

+0

我可以知道簽名將匹配的最小和最大數據長度是多少。如果沒有其他解決方案,我正在考慮一個滑動窗口。說最大的正則表達式匹配將是64個字節。然後,我將不得不以32(64/2)的增量進行滑動,並且窗口的大小爲96(64 + 32)。 I.e .: regex.match(d [0:96]),regex.match(d [32:128]),regex.match(d [64:160])。 – 2015-02-12 08:47:23

+0

@Dogeatcatworld聽起來很合理。滑動窗口實際上就像在不能對文本做出很多假設的情況下逐節處理文件一樣。 – FMc 2015-02-12 09:14:37