Index: Lib/re.py =================================================================== --- Lib/re.py (revision 87986) +++ Lib/re.py (working copy) @@ -214,38 +214,12 @@ "Compile a template pattern, returning a pattern object" return _compile(pattern, flags|T) -_alphanum_str = frozenset( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") -_alphanum_bytes = frozenset( - b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") - def escape(pattern): - "Escape all non-alphanumeric characters in pattern." - if isinstance(pattern, str): - alphanum = _alphanum_str - s = list(pattern) - for i in range(len(pattern)): - c = pattern[i] - if c not in alphanum: - if c == "\000": - s[i] = "\\000" - else: - s[i] = "\\" + c - return "".join(s) - else: - alphanum = _alphanum_bytes - s = [] - esc = ord(b"\\") - for c in pattern: - if c in alphanum: - s.append(c) - else: - if c == 0: - s.extend(b"\\000") - else: - s.append(esc) - s.append(c) - return bytes(s) + "Escape special regex characters in pattern." + specials, repl = r'([][.^$*+?{}\\|()])', r'\\\1' + if isinstance(pattern, bytes): + specials, repl = specials.encode(), repl.encode() + return sub(specials, repl, pattern) # -------------------------------------------------------------------- # internals Index: Lib/test/test_re.py =================================================================== --- Lib/test/test_re.py (revision 87986) +++ Lib/test/test_re.py (working copy) @@ -412,30 +412,32 @@ self.assertEqual(re.search("a\s", "a ").group(0), "a ") def test_re_escape(self): - p="" - self.assertEqual(re.escape(p), p) - for i in range(0, 256): - p = p + chr(i) - self.assertEqual(re.match(re.escape(chr(i)), chr(i)) is not None, - True) - self.assertEqual(re.match(re.escape(chr(i)), chr(i)).span(), (0,1)) + p = "" + for c in {'\0', '_', '!', '\t', p}: + self.assertEqual(re.escape(c), c) + for i in range(256): + c = chr(i) + p += chr(i) + self.assertIsNotNone(re.match(re.escape(c), c)) + self.assertEqual(re.match(re.escape(c), c).span(), (0, 1)) - pat=re.compile(re.escape(p)) - self.assertEqual(pat.match(p) is not None, True) - self.assertEqual(pat.match(p).span(), (0,256)) + pat = re.compile(re.escape(p)) + self.assertIsNotNone(pat.match(p)) + self.assertEqual(pat.match(p).span(), (0, 256)) def test_re_escape_byte(self): - p=b"" - self.assertEqual(re.escape(p), p) - for i in range(0, 256): + p = b"" + for b in {b'\0', b'_', b'!', b'\t', p}: + self.assertEqual(re.escape(b), b) + for i in range(256): b = bytes([i]) p += b - self.assertEqual(re.match(re.escape(b), b) is not None, True) - self.assertEqual(re.match(re.escape(b), b).span(), (0,1)) + self.assertIsNotNone(re.match(re.escape(b), b)) + self.assertEqual(re.match(re.escape(b), b).span(), (0, 1)) - pat=re.compile(re.escape(p)) - self.assertEqual(pat.match(p) is not None, True) - self.assertEqual(pat.match(p).span(), (0,256)) + pat = re.compile(re.escape(p)) + self.assertIsNotNone(pat.match(p)) + self.assertEqual(pat.match(p).span(), (0, 256)) def pickle_test(self, pickle): oldpat = re.compile('a(?:b|(c|e){1,2}?|d)+?(.)')