summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-10-10 08:06:31 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-10-10 08:06:31 (GMT)
commit7438e4b56fa6a34a021f11e1220331e841419b96 (patch)
tree5adea0024d47e6816a9e771423e247faeffab0f6 /Lib
parent365e28238f3ccde7f9024a37c212381746748d54 (diff)
downloadcpython-7438e4b56fa6a34a021f11e1220331e841419b96.zip
cpython-7438e4b56fa6a34a021f11e1220331e841419b96.tar.gz
cpython-7438e4b56fa6a34a021f11e1220331e841419b96.tar.bz2
Issue 1519638: Now unmatched groups are replaced with empty strings in re.sub()
and re.subn().
Diffstat (limited to 'Lib')
-rw-r--r--Lib/sre_parse.py8
-rw-r--r--Lib/test/test_re.py10
2 files changed, 11 insertions, 7 deletions
diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py
index b9a1852..063d1b7 100644
--- a/Lib/sre_parse.py
+++ b/Lib/sre_parse.py
@@ -880,14 +880,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 --git a/Lib/test/test_re.py b/Lib/test/test_re.py
index e5ad6cb..0e4fa88 100644
--- a/Lib/test/test_re.py
+++ b/Lib/test/test_re.py
@@ -225,9 +225,11 @@ class ReTests(unittest.TestCase):
self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<a a>', 'xx')
self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<>', 'xx')
self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<1a1>', 'xx')
+ self.assertRaises(re.error, re.sub, '(?P<a>x)', r'\g<2>', 'xx')
+ self.assertRaises(re.error, re.sub, '(?P<a>x)', r'\2', 'xx')
self.assertRaises(IndexError, re.sub, '(?P<a>x)', '\g<ab>', 'xx')
- self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\g<b>', 'xx')
- self.assertRaises(re.error, re.sub, '(?P<a>x)|(?P<b>y)', '\\2', 'xx')
+ self.assertEqual(re.sub('(?P<a>x)|(?P<b>y)', r'\g<b>', 'xx'), '')
+ self.assertEqual(re.sub('(?P<a>x)|(?P<b>y)', r'\2', 'xx'), '')
self.assertRaises(re.error, re.sub, '(?P<a>x)', '\g<-1>', 'xx')
# New valid/invalid identifiers in Python 3
self.assertEqual(re.sub('(?P<µ>x)', r'\g<µ>', 'xx'), 'xx')
@@ -439,6 +441,10 @@ class ReTests(unittest.TestCase):
"first second")
.expand(r"\2 \1 \g<second> \g<first>"),
"second first second first")
+ self.assertEqual(re.match("(?P<first>first)|(?P<second>second)",
+ "first")
+ .expand(r"\2 \g<second>"),
+ " ")
def test_repeat_minmax(self):
self.assertIsNone(re.match("^(\w){1}$", "abc"))