diff -r a0372781eafb Doc/library/re.rst --- a/Doc/library/re.rst Thu Sep 18 06:05:37 2014 +0300 +++ b/Doc/library/re.rst Thu Sep 18 13:54:11 2014 +0300 @@ -701,6 +701,9 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced by empty string. + .. function:: subn(pattern, repl, string, count=0, flags=0) @@ -710,6 +713,9 @@ form. .. versionchanged:: 3.1 Added the optional flags argument. + .. versionchanged:: 3.5 + Unmatched groups are replaced by empty string. + .. function:: escape(string) @@ -885,6 +891,8 @@ Match objects support the following meth (``\g<1>``, ``\g``) are replaced by the contents of the corresponding group. + .. versionchanged:: 3.5 + Unmatched groups are replaced by empty string. .. method:: match.group([group1, ...]) diff -r a0372781eafb Lib/sre_parse.py --- a/Lib/sre_parse.py Thu Sep 18 06:05:37 2014 +0300 +++ b/Lib/sre_parse.py Thu Sep 18 13:54:11 2014 +0300 @@ -846,14 +846,12 @@ def parse_template(source, pattern): def expand_template(template, match): g = match.group - sep = match.string[:0] + empty = match.string[:0] groups, literals = template literals = literals[:] try: for index, group in groups: - literals[index] = s = g(group) - if s is None: - raise error("unmatched group") + literals[index] = g(group) or empty except IndexError: raise error("invalid group reference") - return sep.join(literals) + return empty.join(literals) diff -r a0372781eafb Lib/test/test_re.py --- a/Lib/test/test_re.py Thu Sep 18 06:05:37 2014 +0300 +++ b/Lib/test/test_re.py Thu Sep 18 13:54:11 2014 +0300 @@ -220,9 +220,11 @@ class ReTests(unittest.TestCase): self.assertRaises(re.error, re.sub, '(?Px)', '\g', 'xx') self.assertRaises(re.error, re.sub, '(?Px)', '\g<>', 'xx') self.assertRaises(re.error, re.sub, '(?Px)', '\g<1a1>', 'xx') + self.assertRaises(re.error, re.sub, '(?Px)', r'\g<2>', 'xx') + self.assertRaises(re.error, re.sub, '(?Px)', r'\2', 'xx') self.assertRaises(IndexError, re.sub, '(?Px)', '\g', 'xx') - self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\g', 'xx') - self.assertRaises(re.error, re.sub, '(?Px)|(?Py)', '\\2', 'xx') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\g', 'xx'), '') + self.assertEqual(re.sub('(?Px)|(?Py)', r'\2', 'xx'), '') self.assertRaises(re.error, re.sub, '(?Px)', '\g<-1>', 'xx') # New valid/invalid identifiers in Python 3 self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx') @@ -427,6 +429,10 @@ class ReTests(unittest.TestCase): "first second") .expand(r"\2 \1 \g \g"), "second first second first") + self.assertEqual(re.match("(?Pfirst)|(?Psecond)", + "first") + .expand(r"\2 \g"), + " ") def test_repeat_minmax(self): self.assertIsNone(re.match("^(\w){1}$", "abc"))