簡體   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