diff options
-rw-r--r-- | Lib/sre.py | 29 | ||||
-rw-r--r-- | Modules/_sre.c | 23 |
2 files changed, 40 insertions, 12 deletions
diff --git a/Lib/sre.py b/Lib/sre.py index 579106bfc1..e6550977ff 100644 --- a/Lib/sre.py +++ b/Lib/sre.py @@ -159,42 +159,47 @@ def _expand(pattern, match, template): template = sre_parse.parse_template(template, pattern) return sre_parse.expand_template(template, match) -def _sub(pattern, template, string, count=0): +def _sub(pattern, template, text, count=0): # internal: pattern.sub implementation hook - return _subn(pattern, template, string, count)[0] + return _subn(pattern, template, text, count, 1)[0] -def _subn(pattern, template, string, count=0): +def _subn(pattern, template, text, count=0, sub=0): # internal: pattern.subn implementation hook if callable(template): filter = template else: template = _compile_repl(template, pattern) + literals = template[1] + if (sub and not count and pattern._isliteral() and + len(literals) == 1 and literals[0]): + # shortcut: both pattern and string are literals + return string.replace(text, pattern.pattern, literals[0]), 0 def filter(match, template=template): return sre_parse.expand_template(template, match) n = i = 0 s = [] append = s.append - c = pattern.scanner(string) + c = pattern.scanner(text) while not count or n < count: m = c.search() if not m: break b, e = m.span() if i < b: - append(string[i:b]) + append(text[i:b]) append(filter(m)) i = e n = n + 1 - append(string[i:]) - return _join(s, string[:0]), n + append(text[i:]) + return _join(s, text[:0]), n -def _split(pattern, string, maxsplit=0): +def _split(pattern, text, maxsplit=0): # internal: pattern.split implementation hook n = i = 0 s = [] append = s.append extend = s.extend - c = pattern.scanner(string) + c = pattern.scanner(text) g = pattern.groups while not maxsplit or n < maxsplit: m = c.search() @@ -202,15 +207,15 @@ def _split(pattern, string, maxsplit=0): break b, e = m.span() if b == e: - if i >= len(string): + if i >= len(text): break continue - append(string[i:b]) + append(text[i:b]) if g and b != e: extend(list(m.groups())) i = e n = n + 1 - append(string[i:]) + append(text[i:]) return s # register myself for pickling diff --git a/Modules/_sre.c b/Modules/_sre.c index 1e5f618c8e..caf47aab29 100644 --- a/Modules/_sre.c +++ b/Modules/_sre.c @@ -1955,6 +1955,28 @@ pattern_deepcopy(PatternObject* self, PyObject* args) #endif } +static PyObject* +pattern_isliteral(PatternObject* self, PyObject* args) +{ + /* internal: return true if pattern consists of literal text only */ + + SRE_CODE* code; + PyObject* isliteral; + + if (!PyArg_ParseTuple(args, ":_isliteral")) + return NULL; + + code = PatternObject_GetCode(self); + + if (code[0] == SRE_OP_INFO && code[2] & SRE_INFO_LITERAL) + isliteral = Py_True; + else + isliteral = Py_False; + + Py_INCREF(isliteral); + return isliteral; +} + static PyMethodDef pattern_methods[] = { {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS}, @@ -1965,6 +1987,7 @@ static PyMethodDef pattern_methods[] = { {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, + {"_isliteral", (PyCFunction) pattern_isliteral, METH_VARARGS}, {NULL, NULL} }; |