在Python中缓存已编译的正则表达式对象?

时间:2008-09-15 18:10:35

标签: python regex caching

每次导入包含大量静态正则表达式的python文件时,都会花费cpu周期将字符串编译到内存中的代表状态机中。

a = re.compile("a.*b")
b = re.compile("c.*d")
...

问题:是否可以以预编译的方式将这些正则表达式存储在磁盘上的缓存中,以避免在每次导入时执行正则表达式编译?

腌制对象只需执行以下操作,无论如何都会导致编译:

>>> import pickle
>>> import re
>>> x = re.compile(".*")
>>> pickle.dumps(x)
"cre\n_compile\np0\n(S'.*'\np1\nI0\ntp2\nRp3\n."

re个对象是不可编组的:

>>> import marshal
>>> import re
>>> x = re.compile(".*")
>>> marshal.dumps(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: unmarshallable object

7 个答案:

答案 0 :(得分:13)

  

是否可以以预编译的方式将这些正则表达式存储在磁盘上的缓存中,以避免在每次导入时执行正则表达式编译?

不容易。您必须编写一个自定义序列化程序,它挂钩到Python正则表达式引擎的C sre实现中。所需的时间和精力将大大超过任何性能优势。

首先,您实际上是否对代码进行了分析?我怀疑编译正则表达式是应用程序运行时的重要部分。请记住,它们仅在第一次在当前执行中导入模块时进行编译 - 此后,模块及其属性将缓存在内存中。

如果你有一个基本上产生一次的程序,编译一堆正则表达式然后退出,你可以尝试重新设计它以在一次调用中执行多个测试。然后你可以重新使用正则表达式,如上所述。

最后,您可以将正则表达式编译为基于C的状态机,然后将它们与扩展模块链接。虽然这可能更难以维护,但它将完全从您的应用程序中消除正则表达式编译。

答案 1 :(得分:2)

请注意,无论您导入多少次,每个模块在应用生命周期内只会初始化一次。因此,如果您在模块的全局范围内编译表达式(即不在函数中),那么您应该没问题。

答案 2 :(得分:1)

首先,这是python re模块的一个明显限制。它会限制正则表达式的合理程度和大小。对于长时间运行的进程,限制更大,对于命令行应用程序等短期进程,限制更小。

几年前我确实看过它,可以挖掘出编译结果,腌制它然后取消它并重新使用它。问题是它需要使用sre.py内部,所以不太可能在不同的python版本中工作。

我想在我的工具箱中使用这种功能。我还想知道,如果有任何单独的模块可以替代使用。

答案 3 :(得分:0)

shelve模块似乎工作正常:


import re
import shelve
a_pattern = "a.*b"
b_pattern = "c.*d"
a = re.compile(a_pattern)
b = re.compile(b_pattern)

x = shelve.open('re_cache')
x[a_pattern] = a
x[b_pattern] = b
x.close()

# ...
x = shelve.open('re_cache')
a = x[a_pattern]
b = x[b_pattern]
x.close()

然后你可以创建一个很好的包装器类来自动处理你的缓存,这样它对用户来说就变得透明了......这个练习留给了读者。

答案 4 :(得分:0)

打开/usr/lib/python2.5/re.py并查找“def _compile”。你会发现re.py的内部缓存机制。

答案 5 :(得分:-1)

可以将每个正则表达式(或正则表达式组)放入单独的文件中,然后使用imp模块动态导入所需的文件。我怀疑它能够很好地扩展,但它可能就是你所需要的。

答案 6 :(得分:-1)

呜呜,

不搁置使用泡菜吗?

无论如何,我同意以前的导师。由于模块只处理一次,我怀疑编译regexps将是你的app瓶颈。并且Python re模块很快就被编写了,因为它是用C编写的: - )

但好消息是Python有一个很好的社区,所以我相信你可以找到一个正在黑客攻击的人。

我用Google搜索了5秒后发现:http://home.gna.org/oomadness/en/cerealizer/index.html

不知道是否会这样做但如果没有,祝你研究好运: - )