Rewritten using regex.
This commit is contained in:
parent
9542c58d45
commit
05e5219f53
116
Lib/fnmatch.py
116
Lib/fnmatch.py
|
@ -1,77 +1,57 @@
|
|||
# module 'fnmatch' -- filename matching with shell patterns
|
||||
# This version translates the pattern to a regular expression
|
||||
# and moreover caches the expressions.
|
||||
|
||||
import os
|
||||
import regex
|
||||
|
||||
cache = {}
|
||||
|
||||
def fnmatch(name, pat):
|
||||
#
|
||||
# Check for simple case: no special characters
|
||||
#
|
||||
if not ('*' in pat or '?' in pat or '[' in pat):
|
||||
return name == pat
|
||||
#
|
||||
# Check for common cases: *suffix and prefix*
|
||||
#
|
||||
if pat[0] == '*':
|
||||
p1 = pat[1:]
|
||||
if not ('*' in p1 or '?' in p1 or '[' in p1):
|
||||
start = len(name) - len(p1)
|
||||
return start >= 0 and name[start:] == p1
|
||||
elif pat[-1:] == '*':
|
||||
p1 = pat[:-1]
|
||||
if not ('*' in p1 or '?' in p1 or '[' in p1):
|
||||
return name[:len(p1)] == p1
|
||||
#
|
||||
# General case
|
||||
#
|
||||
return fnmatch1(name, pat)
|
||||
name = os.path.normcase(name)
|
||||
pat = os.path.normcase(pat)
|
||||
if not cache.has_key(pat):
|
||||
res = translate(pat)
|
||||
save_syntax = regex.set_syntax(0)
|
||||
cache[pat] = regex.compile(res)
|
||||
save_syntax = regex.set_syntax(save_syntax)
|
||||
return cache[pat].match(name) == len(name)
|
||||
|
||||
def fnmatch1(name, pat):
|
||||
def translate(pat):
|
||||
i, n = 0, len(pat)
|
||||
res = ''
|
||||
while i < n:
|
||||
c = pat[i]
|
||||
if c == '*':
|
||||
p1 = pat[i+1:]
|
||||
if not ('*' in p1 or '?' in p1 or '[' in p1):
|
||||
start = len(name) - len(p1)
|
||||
return start >= 0 and name[start:] == p1
|
||||
for i in range(i, len(name) + 1):
|
||||
if fnmatch1(name[i:], p1):
|
||||
return 1
|
||||
return 0
|
||||
elif c == '?':
|
||||
if len(name) <= i : return 0
|
||||
elif c == '[':
|
||||
c, rest = name[i], name[i+1:]
|
||||
i, n = i+1, len(pat) - 1
|
||||
match = 0
|
||||
exclude = 0
|
||||
if i < n and pat[i] == '!':
|
||||
exclude = 1
|
||||
i = i+1
|
||||
while i < n:
|
||||
if pat[i] == c: match = 1
|
||||
i = i+1
|
||||
if i >= n or pat[i] == ']':
|
||||
break
|
||||
if pat[i] == '-':
|
||||
i = i+1
|
||||
if i >= n or pat[i] == ']':
|
||||
break
|
||||
if pat[i-2] <= c <= pat[i]:
|
||||
match = 1
|
||||
i = i+1
|
||||
if i >= n or pat[i] == ']':
|
||||
break
|
||||
if match == exclude:
|
||||
return 0
|
||||
return fnmatch1(rest, pat[i+1:])
|
||||
else:
|
||||
if name[i:i+1] <> c:
|
||||
return 0
|
||||
i = i+1
|
||||
# We don't get here if the pattern contained * or [...]
|
||||
return i >= len(name)
|
||||
|
||||
def fnmatchlist(names, pat):
|
||||
res = []
|
||||
for name in names:
|
||||
if fnmatch(name, pat): res.append(name)
|
||||
if c == '*':
|
||||
res = res + '.*'
|
||||
elif c == '?':
|
||||
res = res + '.'
|
||||
elif c == '[':
|
||||
j = i
|
||||
if j < n and pat[j] == '!':
|
||||
j = j+1
|
||||
if j < n and pat[j] == ']':
|
||||
j = j+1
|
||||
while j < n and pat[j] != ']':
|
||||
j = j+1
|
||||
if j >= n:
|
||||
res = res + '\\['
|
||||
else:
|
||||
stuff = pat[i:j]
|
||||
i = j+1
|
||||
if stuff[0] == '!':
|
||||
stuff = '[^' + stuff[1:] + ']'
|
||||
elif stuff == '^'*len(stuff):
|
||||
stuff = '\\^'
|
||||
else:
|
||||
while stuff[0] == '^':
|
||||
stuff = stuff[1:] + stuff[0]
|
||||
stuff = '[' + stuff + ']'
|
||||
res = res + stuff
|
||||
elif c in '\\.+^$':
|
||||
res = res + ('\\' + c)
|
||||
else:
|
||||
res = res + c
|
||||
print 'translate(' + `pat` + ') == ' + `res`
|
||||
return res
|
||||
|
|
Loading…
Reference in New Issue