繁体   English   中英

循环使用100多个不同的正则表达式时,Python re模块变得慢20倍

[英]Python re module becomes 20 times slower when looping on more than 100 different regex

我的问题是解析日志文件并删除每行上的可变部分以便对它们进行分组。 例如:

s = re.sub(r'(?i)User [_0-9A-z]+ is ', r"User .. is ", s)
s = re.sub(r'(?i)Message rejected because : (.*?) \(.+\)', r'Message rejected because : \1 (...)', s)

我有大约120多个匹配规则,如上所述。

我在100个不同的正则表达式上连续搜索时没有发现任何性能问题。 但是,当应用101个正则表达式时,会发生巨大的减速。

使用替换我的规则时会发生完全相同的行为

for a in range(100):
    s = re.sub(r'(?i)caught here'+str(a)+':.+', r'( ... )', s)

使用范围(101)代替它慢了20倍。

# range(100)
% ./dashlog.py file.bz2
== Took  2.1 seconds.  ==

# range(101)
% ./dashlog.py file.bz2
== Took  47.6 seconds.  ==

为什么会发生这样的事情? 有没有已知的解决方法?

(在Linux / Windows上发生在Python 2.6.6 / 2.7.2上。)

Python为编译的正则表达式保留内部缓存。 每当您使用一个采用正则表达式的顶级函数时,Python首先编译该表达式,并缓存该编译的结果。

猜猜缓存可容纳多少项

>>> import re
>>> re._MAXCACHE
100

当您超过缓存大小时,Python 2会清除所有缓存的表达式 ,并以干净的缓存开始。 Python 3将限制增加到512,但仍然完全清楚。

解决方法是您自己缓存编译:

compiled_expression = re.compile(r'(?i)User [_0-9A-z]+ is ')

compiled_expression.sub(r"User .. is ", s)

您可以使用functools.partial()sub()调用与替换表达式捆绑在一起:

from functools import partial

compiled_expression = re.compile(r'(?i)User [_0-9A-z]+ is ')
ready_to_use_sub = partial(compiled_expression.sub, r"User .. is ")

然后使用ready_to_use_sub(s)将编译的正则表达式模式与特定的替换模式一起使用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM