diff options
author | Guido van Rossum <guido@python.org> | 1992-01-12 23:29:29 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 1992-01-12 23:29:29 (GMT) |
commit | 05e5219f53996f606b93fe42a56771819090e994 (patch) | |
tree | ea2dbd8c6ae35c0af1fa190c833ede6b7cfc898e /Lib/fnmatch.py | |
parent | 9542c58d457c0b6f2fd45bce5f212c992a040d6a (diff) | |
download | cpython-05e5219f53996f606b93fe42a56771819090e994.zip cpython-05e5219f53996f606b93fe42a56771819090e994.tar.gz cpython-05e5219f53996f606b93fe42a56771819090e994.tar.bz2 |
Rewritten using regex.
Diffstat (limited to 'Lib/fnmatch.py')
-rw-r--r-- | Lib/fnmatch.py | 110 |
1 files changed, 45 insertions, 65 deletions
diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py index 549e0e7..c30aaca 100644 --- a/Lib/fnmatch.py +++ b/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] + i = i+1 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 + res = res + '.*' elif c == '?': - if len(name) <= i : return 0 + res = res + '.' 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:]) + 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: - 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) + res = res + c + print 'translate(' + `pat` + ') == ' + `res` return res |