cpython: 8a3807e15a1f (original) (raw)
Mercurial > cpython
changeset 93667:8a3807e15a1f 2.7
Benjamin Peterson benjamin@python.org | |
---|---|
date | Sun, 30 Nov 2014 11:47:54 -0500 |
parents | fee117d5c894 |
children | 961145c548e2 54af09408795 |
files | Lib/re.py Lib/sre_parse.py Lib/test/test_re.py Misc/NEWS |
diffstat | 4 files changed, 12 insertions(+), 67 deletions(-)[+] [-] Lib/re.py 5 Lib/sre_parse.py 33 Lib/test/test_re.py 38 Misc/NEWS 3 |
line wrap: on
line diff
--- a/Lib/re.py +++ b/Lib/re.py @@ -312,11 +312,10 @@ class Scanner: s = sre_parse.Pattern() s.flags = flags for phrase, action in lexicon:
gid = s.opengroup()[](#l1.7) p.append(sre_parse.SubPattern(s, [[](#l1.8)
(SUBPATTERN, (gid, sre_parse.parse(phrase, flags))),[](#l1.9)
(SUBPATTERN, (len(p)+1, sre_parse.parse(phrase, flags))),[](#l1.10) ]))[](#l1.11)
s.closegroup(gid, p[-1])[](#l1.12)
def scan(self, string):s.groups = len(p)+1[](#l1.13) p = sre_parse.SubPattern(s, [(BRANCH, (None, p))])[](#l1.14) self.scanner = sre_compile.compile(p)[](#l1.15)
--- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -66,25 +66,24 @@ class Pattern: # master pattern object. keeps track of global attributes def init(self): self.flags = 0
self.open = [][](#l2.7)
self.groups = 1[](#l2.8) self.groupdict = {}[](#l2.9)
self.subpatterns = [None] # group 0[](#l2.10)
- @property
- def groups(self):
def opengroup(self, name=None): gid = self.groupsreturn len(self.subpatterns)[](#l2.13)
self.subpatterns.append(None)[](#l2.16)
self.groups = gid + 1[](#l2.17) if name is not None:[](#l2.18) ogid = self.groupdict.get(name, None)[](#l2.19) if ogid is not None:[](#l2.20) raise error, ("redefinition of group name %s as group %d; "[](#l2.21) "was group %d" % (repr(name), gid, ogid))[](#l2.22) self.groupdict[name] = gid[](#l2.23)
self.open.append(gid)[](#l2.24) return gid[](#l2.25)
return gid < self.groups and self.subpatterns[gid] is not None[](#l2.31)
return gid < self.groups and gid not in self.open[](#l2.32)
class SubPattern: # a subpattern, in intermediate form @@ -179,21 +178,7 @@ class SubPattern: elif op in UNITCODES: lo = lo + 1 hi = hi + 1
elif op is GROUPREF:[](#l2.40)
i, j = self.pattern.subpatterns[av].getwidth()[](#l2.41)
lo = lo + i[](#l2.42)
hi = hi + j[](#l2.43)
elif op is GROUPREF_EXISTS:[](#l2.44)
i, j = av[1].getwidth()[](#l2.45)
if av[2] is not None:[](#l2.46)
l, h = av[2].getwidth()[](#l2.47)
i = min(i, l)[](#l2.48)
j = max(j, h)[](#l2.49)
else:[](#l2.50)
i = 0[](#l2.51)
lo = lo + i[](#l2.52)
hi = hi + j[](#l2.53)
elif op is SUCCESS:[](#l2.54)
elif op == SUCCESS:[](#l2.55) break[](#l2.56) self.width = min(lo, MAXREPEAT - 1), min(hi, MAXREPEAT)[](#l2.57) return self.width[](#l2.58)
@@ -672,7 +657,7 @@ def _parse(source, state): if not sourcematch(")"): raise error, "unbalanced parenthesis" if group is not None:
state.closegroup(group, p)[](#l2.63)
state.closegroup(group)[](#l2.64) subpatternappend((SUBPATTERN, (group, p)))[](#l2.65) else:[](#l2.66) while 1:[](#l2.67)
--- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -449,7 +449,7 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match("a.*b", "a\n\nb", re.DOTALL).group(0), "a\n\nb")
- def test_non_consuming(self): self.assertEqual(re.match("(a(?=\s[^a]))", "a b").group(1), "a") self.assertEqual(re.match("(a(?=\s[^a]*))", "a b").group(1), "a") self.assertEqual(re.match("(a(?=\s[abc]))", "a b").group(1), "a")
@@ -463,42 +463,6 @@ class ReTests(unittest.TestCase): self.assertEqual(re.match(r"(a)(?!\s\1)", "a b").group(1), "a") self.assertEqual(re.match(r"(a)(?!\s(abc|a))", "a b").group(1), "a")
# Group reference.[](#l3.16)
self.assertTrue(re.match(r'(a)b(?=\1)a', 'aba'))[](#l3.17)
self.assertIsNone(re.match(r'(a)b(?=\1)c', 'abac'))[](#l3.18)
# Conditional group reference.[](#l3.19)
self.assertTrue(re.match('(?:(a)|(x))b(?=(?(2)x|c))c', 'abc'))[](#l3.20)
self.assertIsNone(re.match('(?:(a)|(x))b(?=(?(2)c|x))c', 'abc'))[](#l3.21)
self.assertTrue(re.match('(?:(a)|(x))b(?=(?(2)x|c))c', 'abc'))[](#l3.22)
self.assertIsNone(re.match('(?:(a)|(x))b(?=(?(1)b|x))c', 'abc'))[](#l3.23)
self.assertTrue(re.match('(?:(a)|(x))b(?=(?(1)c|x))c', 'abc'))[](#l3.24)
# Group used before defined.[](#l3.25)
self.assertTrue(re.match('(a)b(?=(?(2)x|c))(c)', 'abc'))[](#l3.26)
self.assertIsNone(re.match('(a)b(?=(?(2)b|x))(c)', 'abc'))[](#l3.27)
self.assertTrue(re.match('(a)b(?=(?(1)c|x))(c)', 'abc'))[](#l3.28)
- def test_lookbehind(self):
self.assertTrue(re.match('ab(?<=b)c', 'abc'))[](#l3.31)
self.assertIsNone(re.match('ab(?<=c)c', 'abc'))[](#l3.32)
self.assertIsNone(re.match('ab(?<!b)c', 'abc'))[](#l3.33)
self.assertTrue(re.match('ab(?<!c)c', 'abc'))[](#l3.34)
# Group reference.[](#l3.35)
self.assertTrue(re.match(r'(a)a(?<=\1)c', 'aac'))[](#l3.36)
self.assertIsNone(re.match(r'(a)b(?<=\1)a', 'abaa'))[](#l3.37)
self.assertIsNone(re.match(r'(a)a(?<!\1)c', 'aac'))[](#l3.38)
self.assertTrue(re.match(r'(a)b(?<!\1)a', 'abaa'))[](#l3.39)
# Conditional group reference.[](#l3.40)
self.assertIsNone(re.match('(?:(a)|(x))b(?<=(?(2)x|c))c', 'abc'))[](#l3.41)
self.assertIsNone(re.match('(?:(a)|(x))b(?<=(?(2)b|x))c', 'abc'))[](#l3.42)
self.assertTrue(re.match('(?:(a)|(x))b(?<=(?(2)x|b))c', 'abc'))[](#l3.43)
self.assertIsNone(re.match('(?:(a)|(x))b(?<=(?(1)c|x))c', 'abc'))[](#l3.44)
self.assertTrue(re.match('(?:(a)|(x))b(?<=(?(1)b|x))c', 'abc'))[](#l3.45)
# Group used before defined.[](#l3.46)
self.assertIsNone(re.match('(a)b(?<=(?(2)x|c))(c)', 'abc'))[](#l3.47)
self.assertIsNone(re.match('(a)b(?<=(?(2)b|x))(c)', 'abc'))[](#l3.48)
self.assertIsNone(re.match('(a)b(?<=(?(1)c|x))(c)', 'abc'))[](#l3.49)
self.assertTrue(re.match('(a)b(?<=(?(1)b|x))(c)', 'abc'))[](#l3.50)
- def test_ignore_case(self): self.assertEqual(re.match("abc", "ABC", re.I).group(0), "ABC") self.assertEqual(re.match("abc", u"ABC", re.I).group(0), "ABC")
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -72,9 +72,6 @@ Library
- Issue #22821: Fixed fcntl() with integer argument on 64-bit big-endian platforms. -- Issues #814253, #9179: Group references and conditional group references now
- work in lookbehind assertions in regular expressions. -
- Issue #17293: uuid.getnode() now determines MAC address on AIX using netstat. Based on patch by Aivars KalvÄns.