【问题标题】:Execution Time increases while using re.search in python在 python 中使用 re.search 时执行时间增加
【发布时间】:2013-03-07 02:01:35
【问题描述】:

我正在处理一个 500MB 的文件。使用re.search时处理时间增加。

请找出我测试过的以下案例。在所有情况下,我都在逐行读取文件并且只使用一个if 条件。

案例1:

prnt = re.compile(r"(?i)<spanlevel level='7'>")
if prnt.search(line):
print "Matched"
out_file.write(line)
else:
out_file.write(line) 

读取整个文件需要 16 秒。

案例2:

if re.search(r"(?i)<spanlevel level='7'>",line):
print "Matched"
out_file.write(line)
else:
out_file.write(line)

读取文件需要 25 秒。

案例3:

if "<spanlevel level='7'>" in line:
print "Matched"
out_file.write(line)
else:
out_file.write(line)

读取文件仅需 8 秒。

请你们中的任何人知道这三种情况之间的区别。 Case3 的处理速度非常快,但我无法进行不区分大小写的匹配。如何在 Case3 中进行不区分大小写的匹配?

【问题讨论】:

  • 一般来说,当你不需要正则表达式时,不要使用它。正则表达式通常比字符扫描或 indexOf 更昂贵
  • 您使用的是 Python 2 语法,但用 python-3.x 标记了它。它是什么,python 2 还是 3?
  • @MartijnPieters 我正在使用 python 2.7
  • 最快的方法可能是克隆fastsearch后面的str.find的C实现,修改为不区分大小写,构建ifind扩展模块,然后针对文件的mmap 运行它。但这是很多工作。除非有人已经完成并将其发布在 PyPI 上,或者这对您的工作非常重要,否则您的“案例 1”或 Martijn Pieters 的答案可能就足够了,对吧?

标签: python regex


【解决方案1】:

不区分大小写,首先搜索 case 3:

if "<spanlevel level='7'>" in line.lower():

通过小写line,您可以进行小写搜索。

至于为什么情况 2 慢得多:使用预编译的正则表达式会更快,因为这样您就可以避免从文件中读取的每一行的正则表达式模式的缓存查找。在底层,re.search() 也将调用 re.compile(),如果不存在缓存副本并且额外的函数调用和缓存检查将花费您。

这对 Python 3.3 来说是双重痛苦,它使用functools.lru_cache decorator 切换到新的缓存模型,实际上比以前的实现慢。见Why are uncompiled, repeatedly used regexes so much slower in Python 3?

使用in 进行简单的文本搜索可以更快地进行精确文本匹配。正则表达式非常适合复杂匹配,您只是在寻找完全匹配,尽管不区分大小写。

【讨论】:

  • 不完全相关,但在mmap 文件上使用re.finditer 也可能是一个合适的替代方案。
  • Martijn:它看起来不像 OP 使用 Python 3。
  • @martineau:我查看了标签。虽然使用print 语句不协调。
  • @martineau:谢谢指出,问题标签确实不正确。
  • Martijn:当然……即使它不适用,您在回答中关于 Py 3.3 问题的参考资料也是很好的传播信息。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-08
  • 1970-01-01
  • 1970-01-01
  • 2018-01-02
  • 1970-01-01
  • 2018-10-01
相关资源
最近更新 更多