Kaydet (Commit) dc5de3ba authored tarafından Tim Peters's avatar Tim Peters

ellipsis_match(): Changed treatment of start- and end-of-string exact

matches to be symmetric.  This makes the algorithm easier to understand.
üst 336e85f5
......@@ -364,47 +364,57 @@ class _SpoofOut(StringIO):
# Worst-case linear-time ellipsis matching.
def ellipsis_match(want, got):
"""
Essentially the only subtle case:
>>> ellipsis_match('aa...aa', 'aaa')
False
"""
if ELLIPSIS_MARKER not in want:
return want == got
# Remove \n from ...\n, else the newline will be required,
# and (for example) ... on a line by itself can't match
# nothing gracefully.
want = want.replace(ELLIPSIS_MARKER + '\n', ELLIPSIS_MARKER)
# Find "the real" strings.
ws = want.split(ELLIPSIS_MARKER)
assert len(ws) >= 2
# Match. In general, we only need to find the leftmost non-overlapping
# match for each piece. "Real strings" at the start or end of `want`
# are special cases.
# Deal with exact matches possibly needed at one or both ends.
startpos, endpos = 0, len(got)
w = ws[0]
if w:
# An ellipsis didn't start `want`. We need to match exactly
# at the start.
if not got.startswith(w):
if w: # starts with exact match
if got.startswith(w):
startpos = len(w)
del ws[0]
else:
return False
w = ws[-1]
if w: # ends with exact match
if got.endswith(w):
endpos -= len(w)
del ws[-1]
else:
return False
pos = len(w)
del ws[0]
else:
pos = 0
if startpos > endpos:
# Exact end matches required more characters than we have, as in
# ellipsis_match('aa...aa', 'aaa')
return False
# For the rest, we only need to find the leftmost non-overlapping
# match for each piece. If there's no overall match that way alone,
# there's no overall match period.
for w in ws:
# w may be '' at times, if there are consecutive ellipses, or
# due to an ellipsis at the start or end of `want`. That's OK.
# Search for an empty string succeeds, and doesn't change pos.
pos = got.find(w, pos)
if pos < 0:
# Search for an empty string succeeds, and doesn't change startpos.
startpos = got.find(w, startpos, endpos)
if startpos < 0:
return False
pos += len(w)
# If `want` ended with an ellipsis, the tail matches anything.
if ws[-1] == '':
return True
# Else `want` ended with a real string. If the last real match
# exhausted `got`, we win.
if pos == len(got):
return True
# Else maybe we matched the last real string too early.
return got.endswith(ws[-1])
startpos += len(w)
return True
######################################################################
## 2. Example & DocTest
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment