Commit 2d96f11d authored by Fredrik Lundh's avatar Fredrik Lundh

map re.sub() to string.replace(), when possible

parent 44835d8e
...@@ -159,42 +159,47 @@ def _expand(pattern, match, template): ...@@ -159,42 +159,47 @@ def _expand(pattern, match, template):
template = sre_parse.parse_template(template, pattern) template = sre_parse.parse_template(template, pattern)
return sre_parse.expand_template(template, match) 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 # 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 # internal: pattern.subn implementation hook
if callable(template): if callable(template):
filter = template filter = template
else: else:
template = _compile_repl(template, pattern) 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): def filter(match, template=template):
return sre_parse.expand_template(template, match) return sre_parse.expand_template(template, match)
n = i = 0 n = i = 0
s = [] s = []
append = s.append append = s.append
c = pattern.scanner(string) c = pattern.scanner(text)
while not count or n < count: while not count or n < count:
m = c.search() m = c.search()
if not m: if not m:
break break
b, e = m.span() b, e = m.span()
if i < b: if i < b:
append(string[i:b]) append(text[i:b])
append(filter(m)) append(filter(m))
i = e i = e
n = n + 1 n = n + 1
append(string[i:]) append(text[i:])
return _join(s, string[:0]), n return _join(s, text[:0]), n
def _split(pattern, string, maxsplit=0): def _split(pattern, text, maxsplit=0):
# internal: pattern.split implementation hook # internal: pattern.split implementation hook
n = i = 0 n = i = 0
s = [] s = []
append = s.append append = s.append
extend = s.extend extend = s.extend
c = pattern.scanner(string) c = pattern.scanner(text)
g = pattern.groups g = pattern.groups
while not maxsplit or n < maxsplit: while not maxsplit or n < maxsplit:
m = c.search() m = c.search()
...@@ -202,15 +207,15 @@ def _split(pattern, string, maxsplit=0): ...@@ -202,15 +207,15 @@ def _split(pattern, string, maxsplit=0):
break break
b, e = m.span() b, e = m.span()
if b == e: if b == e:
if i >= len(string): if i >= len(text):
break break
continue continue
append(string[i:b]) append(text[i:b])
if g and b != e: if g and b != e:
extend(list(m.groups())) extend(list(m.groups()))
i = e i = e
n = n + 1 n = n + 1
append(string[i:]) append(text[i:])
return s return s
# register myself for pickling # register myself for pickling
......
...@@ -1955,6 +1955,28 @@ pattern_deepcopy(PatternObject* self, PyObject* args) ...@@ -1955,6 +1955,28 @@ pattern_deepcopy(PatternObject* self, PyObject* args)
#endif #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[] = { static PyMethodDef pattern_methods[] = {
{"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS}, {"match", (PyCFunction) pattern_match, METH_VARARGS|METH_KEYWORDS},
{"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS}, {"search", (PyCFunction) pattern_search, METH_VARARGS|METH_KEYWORDS},
...@@ -1965,6 +1987,7 @@ static PyMethodDef pattern_methods[] = { ...@@ -1965,6 +1987,7 @@ static PyMethodDef pattern_methods[] = {
{"scanner", (PyCFunction) pattern_scanner, METH_VARARGS}, {"scanner", (PyCFunction) pattern_scanner, METH_VARARGS},
{"__copy__", (PyCFunction) pattern_copy, METH_VARARGS}, {"__copy__", (PyCFunction) pattern_copy, METH_VARARGS},
{"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS}, {"__deepcopy__", (PyCFunction) pattern_deepcopy, METH_VARARGS},
{"_isliteral", (PyCFunction) pattern_isliteral, METH_VARARGS},
{NULL, NULL} {NULL, NULL}
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment