]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
map re.sub() to string.replace(), when possible
authorFredrik Lundh <fredrik@pythonware.com>
Sun, 8 Jul 2001 13:26:57 +0000 (13:26 +0000)
committerFredrik Lundh <fredrik@pythonware.com>
Sun, 8 Jul 2001 13:26:57 +0000 (13:26 +0000)
Lib/sre.py
Modules/_sre.c

index 579106bfc138286ab010d399e0b4be1b200b0e64..e6550977fffc8022a3b8bb55ae88515c5ae8b38b 100644 (file)
@@ -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
index 1e5f618c8e3c39b3a55a326a1c409bc4255a1850..caf47aab29a3ae6e71b6ae5a5183724242ab7f53 100644 (file)
@@ -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}
 };