]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Rewritten using regex.
authorGuido van Rossum <guido@python.org>
Sun, 12 Jan 1992 23:29:29 +0000 (23:29 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 12 Jan 1992 23:29:29 +0000 (23:29 +0000)
Lib/fnmatch.py

index 549e0e7f01859e8781ce1073d671fc599e39867f..c30aaca998b695520a5328902c32b664279af6a9 100644 (file)
@@ -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