summaryrefslogtreecommitdiff
path: root/Lib/re.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/re.py')
-rw-r--r--Lib/re.py53
1 files changed, 21 insertions, 32 deletions
diff --git a/Lib/re.py b/Lib/re.py
index 309afef125..3fd59df8bc 100644
--- a/Lib/re.py
+++ b/Lib/re.py
@@ -118,6 +118,7 @@ This module also defines an exception 'error'.
import sys
import sre_compile
import sre_parse
+import functools
# public symbols
__all__ = [ "match", "search", "sub", "subn", "split", "findall",
@@ -178,14 +179,19 @@ def subn(pattern, repl, string, count=0, flags=0):
def split(pattern, string, maxsplit=0, flags=0):
"""Split the source string by the occurrences of the pattern,
- returning a list containing the resulting substrings."""
+ returning a list containing the resulting substrings. If
+ capturing parentheses are used in pattern, then the text of all
+ groups in the pattern are also returned as part of the resulting
+ list. If maxsplit is nonzero, at most maxsplit splits occur,
+ and the remainder of the string is returned as the final element
+ of the list."""
return _compile(pattern, flags).split(string, maxsplit)
def findall(pattern, string, flags=0):
"""Return a list of all non-overlapping matches in the string.
- If one or more groups are present in the pattern, return a
- list of groups; this will be a list of tuples if the pattern
+ If one or more capturing groups are present in the pattern, return
+ a list of groups; this will be a list of tuples if the pattern
has more than one group.
Empty matches are included in the result."""
@@ -205,9 +211,9 @@ def compile(pattern, flags=0):
return _compile(pattern, flags)
def purge():
- "Clear the regular expression cache"
- _cache.clear()
- _cache_repl.clear()
+ "Clear the regular expression caches"
+ _compile_typed.cache_clear()
+ _compile_repl.cache_clear()
def template(pattern, flags=0):
"Compile a template pattern, returning a pattern object"
@@ -248,20 +254,14 @@ def escape(pattern):
# --------------------------------------------------------------------
# internals
-_cache = {}
-_cache_repl = {}
-
_pattern_type = type(sre_compile.compile("", 0))
-_MAXCACHE = 100
+def _compile(pattern, flags):
+ return _compile_typed(type(pattern), pattern, flags)
-def _compile(*key):
+@functools.lru_cache(maxsize=500)
+def _compile_typed(text_bytes_type, pattern, flags):
# internal: compile pattern
- cachekey = (type(key[0]),) + key
- p = _cache.get(cachekey)
- if p is not None:
- return p
- pattern, flags = key
if isinstance(pattern, _pattern_type):
if flags:
raise ValueError(
@@ -269,23 +269,12 @@ def _compile(*key):
return pattern
if not sre_compile.isstring(pattern):
raise TypeError("first argument must be string or compiled pattern")
- p = sre_compile.compile(pattern, flags)
- if len(_cache) >= _MAXCACHE:
- _cache.clear()
- _cache[cachekey] = p
- return p
+ return sre_compile.compile(pattern, flags)
-def _compile_repl(*key):
+@functools.lru_cache(maxsize=500)
+def _compile_repl(repl, pattern):
# internal: compile replacement pattern
- p = _cache_repl.get(key)
- if p is not None:
- return p
- repl, pattern = key
- p = sre_parse.parse_template(repl, pattern)
- if len(_cache_repl) >= _MAXCACHE:
- _cache_repl.clear()
- _cache_repl[key] = p
- return p
+ return sre_parse.parse_template(repl, pattern)
def _expand(pattern, match, template):
# internal: match.expand implementation hook
@@ -342,7 +331,7 @@ class Scanner:
if i == j:
break
action = self.lexicon[m.lastindex-1][1]
- if hasattr(action, "__call__"):
+ if callable(action):
self.match = m
action = action(self, m.group())
if action is not None: