2015-02-12 71 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