summaryrefslogtreecommitdiff
path: root/Lib/fnmatch.py
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>1992-01-12 23:29:29 +0000
committerGuido van Rossum <guido@python.org>1992-01-12 23:29:29 +0000
commit05e5219f53996f606b93fe42a56771819090e994 (patch)
treeea2dbd8c6ae35c0af1fa190c833ede6b7cfc898e /Lib/fnmatch.py
parent9542c58d457c0b6f2fd45bce5f212c992a040d6a (diff)
downloadcpython-git-05e5219f53996f606b93fe42a56771819090e994.tar.gz
Rewritten using regex.
Diffstat (limited to 'Lib/fnmatch.py')
-rw-r--r--Lib/fnmatch.py110
1 files changed, 45 insertions, 65 deletions
diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py
index 549e0e7f01..c30aaca998 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