这是(CPython)的实现re.search
:
def search(pattern, string, flags=0):
"""Scan through string looking for a match to the pattern, returning
a match object, or None if no match was found."""
return _compile(pattern, flags).search(string)
这是re.compile
:
def compile(pattern, flags=0):
"Compile a regular expression pattern, returning a pattern object."
return _compile(pattern, flags)
这依赖于re._compile
:
def _compile(*key):
# internal: compile pattern
cachekey = (type(key[0]),) + key
p = _cache.get(cachekey) #_cache is a dict.
if p is not None:
return p
pattern, flags = key
if isinstance(pattern, _pattern_type):
if flags:
raise ValueError('Cannot process flags argument with a compiled pattern')
return pattern
if not sre_compile.isstring(pattern):
raise TypeError, "first argument must be string or compiled pattern"
try:
p = sre_compile.compile(pattern, flags)
except error, v:
raise error, v # invalid expression
if len(_cache) >= _MAXCACHE:
_cache.clear()
_cache[cachekey] = p
return p
所以你可以看到,只要正则表达式已经在字典中,唯一涉及的额外工作就是在字典中查找(这涉及创建一些临时元组,一些额外的函数调用......)。
更新
在过去的美好时光(上面复制的代码),缓存过大时会完全失效。这些天来,缓存循环——首先丢弃最旧的项目。此实现依赖于 python 字典的顺序(这是在 python3.7 之前的实现细节)。在 python3.6 之前的 Cpython 中,这会从缓存中删除一个任意值(可以说这仍然比使整个缓存无效更好)