我正在开发一个名为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 :(得分: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)
但如果文件太大而无法记忆,那么这并不能解决您的问题。
答案 1 :(得分:0)
如果您不需要匹配对象但只匹配字符串,可以考虑使用re.findall()
吗?如果文件太大,你可以按照你的建议将它切成零件,但是使用一些重叠,不要错过任何正则表达式(如果你知道正则表达式的性质,也许它可以找出应该有多大的重叠)。