繁体   English   中英

在Python中编译正则表达式

[英]Compiling Regular Expressions in Python

我正在研究Doug Hellman的“示例中的Python标准库”并且遇到了这个:

“1.3.2编译表达式包括用于将正则表达式作为文本字符串处理的模块级函数,但编译程序经常使用的表达式更有效。”

我不能按照他的解释为什么会这样。 他说“模块级函数维护编译表达式的缓存”,并且由于“缓存大小”有限,“使用编译表达式直接避免了缓存查找开销。”

如果有人可以解释或指导我解释一下,我可以更好地理解为什么编译程序经常使用的正则表达式更有效,以及这个过程实际如何工作,我将非常感激。

嗯。 这很奇怪。 到目前为止,我的知识( 从这个问题获得了其他来源)提出了我的初步答案:


第一个答案

Python缓存您使用的最后100个正则表达式,因此即使您没有显式编译它们,也不必在每次使用时重新编译它们。

但是,有两个缺点:当达到100个正则表达式的限制时,整个缓存都会被破坏,因此如果连续使用101个不同的正则表达式,每次都会重新编译每个正则表达式。 嗯,这不太可能,但仍然。

其次,为了找出是否已经编译了正则表达式,解释器需要每次都在缓存中查找正则表达式,这需要花费一些额外的时间(但由于字典查找速度非常快)。

因此,如果您显式编译正则表达式,则可以避免这个额外的查找步骤。


更新

我刚做了一些测试(Python 3.3):

>>> import timeit
>>> timeit.timeit(setup="import re", stmt='''r=re.compile(r"\w+")\nfor i in range(10):\n r.search("  jkdhf  ")''')
18.547793477671938
>>> timeit.timeit(setup="import re", stmt='''for i in range(10):\n re.search(r"\w+","  jkdhf  ")''')
106.47892003890324

所以似乎没有进行缓存。 也许这是timeit.timeit()运行的特殊条件的怪癖?

另一方面,在Python 2.7中,差异并不明显:

>>> import timeit
>>> timeit.timeit(setup="import re", stmt='''r=re.compile(r"\w+")\nfor i in range(10):\n r.search("  jkdhf  ")''')
7.248294908492429
>>> timeit.timeit(setup="import re", stmt='''for i in range(10):\n re.search(r"\w+","  jkdhf  ")''')
18.26713670282241

我相信他想说的是你不应该在你的循环中编译你的正则表达式,而是在它之外。 然后,您可以在循环内运行已编译的代码。

代替:

while true: 
    result = re.match('A', str)

你应该把:

regex = re.compile('A')
while true:
    result = regex.match(str)

基本上 re.match(pattern, str)结合了编译和匹配步骤。 在循环内编译相同的模式是低效的,因此应该在循环之外提升。

请参阅Tim对正确推理的回答。

听起来像是作者只是说编译正则表达式更有效并保存,而不是指望它仍然保存在模块的有限大小的内部缓存中的先前编译版本。 这可能是因为编译它们所需的工作量加上必须首先发生的额外缓存查找开销大于客户端只是简单地存储它们本身。

暂无
暂无

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

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