gpt4 book ai didi

python - 有没有办法在python中真正 pickle 编译的正则表达式?

转载 作者:IT老高 更新时间:2023-10-28 21:02:09 26 4
gpt4 key购买 nike

我有一个包含 300 多个正则表达式的 Python 控制台应用程序。每个版本的正则表达式集都是固定的。当用户运行应用程序时,整套正则表达式将被应用到任何地方,从一次(一个非常短的工作)到数千次(一个很长的工作)。

我想通过预先编译正则表达式来加速较短的作业,将已编译的正则表达式 pickle 到一个文件中,然后在应用程序运行时加载该文件。

python re 模块很高效,正则表达式的编译开销对于长时间的工作来说是完全可以接受的。然而,对于短作业,它占整个运行时间的很大一部分。一些用户会希望运行许多小型作业以适应他们现有的工作流程。编译正则表达式大约需要 80 毫秒。一个简短的工作可能需要 20 毫秒到 100 毫秒,不包括正则表达式编译。因此,对于短期工作,开销可能是 100% 或更多。这适用于 Windows 和 Linux 下的 Python27。

正则表达式必须与 DOTALL 标志一起应用,因此需要在使用前进行编译。在这种情况下,大型编译缓存显然无济于事。正如一些人所指出的,序列化编译的正则表达式的默认方法实际上并没有多大作用。

re 和 sre 模块将模式编译成带有自己的操作码和一些辅助数据结构(例如,用于表达式中的字符集)的小型自定义语言。 re.py 中的 pickle 函数采取了简单的方法。它是:

def _pickle(p):
return _compile, (p.pattern, p.flags)

copy_reg.pickle(_pattern_type, _pickle, _compile)

我认为该问题的一个好的解决方案是更新 re.py 中 _pickle 的定义,它实际上 pickle 了已编译的模式对象。不幸的是,这超出了我的 Python 技能。不过,我敢打赌,这里有人知道怎么做。

我意识到我不是第一个提出这个问题的人 - 但也许你可以成为第一个给出准确而有用的回答的人!

您的建议将不胜感激。

最佳答案

好的,这不是很漂亮,但它可能是你想要的。我查看了 Python 2.6 中的 sre_compile.py 模块,撕掉了一点,把它切成两半,然后用这两部分来 pickle 和解开编译过的正则表达式:

import re, sre_compile, sre_parse, _sre
import cPickle as pickle

# the first half of sre_compile.compile
def raw_compile(p, flags=0):
# internal: convert pattern list to internal format

if sre_compile.isstring(p):
pattern = p
p = sre_parse.parse(p, flags)
else:
pattern = None

code = sre_compile._code(p, flags)

return p, code

# the second half of sre_compile.compile
def build_compiled(pattern, p, flags, code):
# print code

# XXX: <fl> get rid of this limitation!
if p.pattern.groups > 100:
raise AssertionError(
"sorry, but this version only supports 100 named groups"
)

# map in either direction
groupindex = p.pattern.groupdict
indexgroup = [None] * p.pattern.groups
for k, i in groupindex.items():
indexgroup[i] = k

return _sre.compile(
pattern, flags | p.pattern.flags, code,
p.pattern.groups-1,
groupindex, indexgroup
)

def pickle_regexes(regexes):
picklable = []
for r in regexes:
p, code = raw_compile(r, re.DOTALL)
picklable.append((r, p, code))
return pickle.dumps(picklable)

def unpickle_regexes(pkl):
regexes = []
for r, p, code in pickle.loads(pkl):
regexes.append(build_compiled(r, p, re.DOTALL, code))
return regexes

regexes = [
r"^$",
r"a*b+c*d+e*f+",
]

pkl = pickle_regexes(regexes)
print pkl
print unpickle_regexes(pkl)

我真的不知道这是否有效,或者它是否加快了速度。我知道当我尝试它时它会打印一个正则表达式列表。它可能非常特定于 2.6 版,我也不知道。

关于python - 有没有办法在python中真正 pickle 编译的正则表达式?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4037339/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com