diff --git a/Doc/library/re.rst b/Doc/library/re.rst index 3e9cf026f07..b1c3804b67b 100644 --- a/Doc/library/re.rst +++ b/Doc/library/re.rst @@ -689,9 +689,12 @@ form. .. function:: escape(string) - Return *string* with all non-alphanumerics backslashed; this is useful if you - want to match an arbitrary literal string that may have regular expression - metacharacters in it. + Escape all the characters in pattern except ASCII letters, numbers and ``'_'``. + This is useful if you want to match an arbitrary literal string that may + have regular expression metacharacters in it. + + .. versionchanged:: 3.3 + The ``'_'`` character is no longer escaped. .. function:: purge() diff --git a/Lib/re.py b/Lib/re.py index abd7ea27b32..cdf597627f0 100644 --- a/Lib/re.py +++ b/Lib/re.py @@ -215,12 +215,14 @@ def template(pattern, flags=0): return _compile(pattern, flags|T) _alphanum_str = frozenset( - "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") + "_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") _alphanum_bytes = frozenset( - b"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") + b"_abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890") def escape(pattern): - "Escape all non-alphanumeric characters in pattern." + """ + Escape all the characters in pattern except ASCII letters, numbers and '_'. + """ if isinstance(pattern, str): alphanum = _alphanum_str s = list(pattern) diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index fe8bc340394..e3d10f73524 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -428,7 +428,7 @@ class ReTests(unittest.TestCase): self.assertEqual(m.span(), span) def test_re_escape(self): - alnum_chars = string.ascii_letters + string.digits + alnum_chars = string.ascii_letters + string.digits + '_' p = ''.join(chr(i) for i in range(256)) for c in p: if c in alnum_chars: @@ -441,7 +441,7 @@ class ReTests(unittest.TestCase): self.assertMatch(re.escape(p), p) def test_re_escape_byte(self): - alnum_chars = (string.ascii_letters + string.digits).encode('ascii') + alnum_chars = (string.ascii_letters + string.digits + '_').encode('ascii') p = bytes(range(256)) for i in p: b = bytes([i]) diff --git a/Misc/NEWS b/Misc/NEWS index fdd410b77d5..9d6307469c6 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -98,6 +98,8 @@ Core and Builtins Library ------- +- Issue #2650: re.escape() no longer escapes the '_'. + - Issue #11757: select.select() now raises ValueError when a negative timeout is passed (previously, a select.error with EINVAL would be raised). Patch by Charles-François Natali.