【发布时间】:2015-09-18 19:15:05
【问题描述】:
我读了一篇很酷的article,关于如何避免创建缓慢的正则表达式。一般来说,它看起来越长越明确,而正则表达式完成的速度越快。贪婪的正则表达式可能会以指数方式变慢。
我想我会通过测量用不太复杂/贪婪的语句完成更复杂/明确的语句所需的时间来测试这一点。在大多数情况下,一切似乎都是正确的,但我有一个贪婪的陈述,速度变慢了。这里有两个例子:
import re
from timeit import timeit
# This works as expected, the explicit is faster than the greedy.
# http_x_real_ip explicit
print(timeit(setup="import re", stmt='''r = re.search(r'(\d{1,3}\.\d{1,3}.\d{1,3}.\d{1,3})', '192.168.1.1 999.999.999.999')''', number=1000000))
1.159849308001867
# http_x_real_ip greedy
print(timeit(setup="import re", stmt='''r = re.search(r'((?:\d{1,3}\.){3}\d{1,3})', '192.168.1.1 999.999.999.999')''', number=1000000))
1.7421739230003368
# This does not work as expected, greedy is faster.
# time_local explicit
print(timeit(setup="import re", stmt='''r = re.search(r'(\d{1,2}/\w{3}/[2][0]\d{2}:\d{2}:\d{2}:\d{2}\s[+][0]{4})', "[23/Jun/2015:11:10:57 +0000]")''', number=1000000))
1.248802040994633
# time_local greedy
print(timeit(setup="import re", stmt='''r = re.search(r'\[(.*)\]', "[23/Jun/2015:11:10:57 +0000]")''', number=1000000))
1.0256699790043058
local_time 显式正则表达式是否写得不好?
【问题讨论】:
-
time_local 贪心是不等价的。它只匹配
[]之间的任何内容。 -
也许 time_local 贪婪的执行速度比预期的要快?
-
time_local greedy 的执行速度比预期的要快......也许如果被解析的字符串相当长,例如完整的日志条目,由于额外的回溯,它会花费更长的时间?我得试试看。
-
您的最后一个模式更快,因为正则表达式引擎需要考虑的标记很少,而且只需一个回溯步骤即可使模式成功。
-
请注意,第一个模式是错误的,因为您忘记了转义点。
标签: python regex performance