在Python中编译正则表达式

use*_*186 4 python regex compilation

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

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

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

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

Tim*_*ker 8

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


第一个答案

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
Run Code Online (Sandbox Code Playgroud)

所以似乎没有进行缓存.也许这是特殊条件下的一个怪癖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
Run Code Online (Sandbox Code Playgroud)