]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Support [...] ranges. Also [!...] for negated ranges, SYSV shell style.
authorGuido van Rossum <guido@python.org>
Sun, 7 Apr 1991 13:40:02 +0000 (13:40 +0000)
committerGuido van Rossum <guido@python.org>
Sun, 7 Apr 1991 13:40:02 +0000 (13:40 +0000)
Lib/fnmatch.py

index c7caef6f279379c991f0caaa4fe655ed3b0d518a..1e7dbb31889129343c8a4b9017613a1246de5ca8 100644 (file)
@@ -1,28 +1,64 @@
 # module 'fnmatch' -- filename matching with shell patterns
 
-# XXX [] patterns are not supported (but recognized)
-
 def fnmatch(name, pat):
-       if '*' in pat or '?' in pat or '[' in pat:
-               return fnmatch1(name, pat)
-       return 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)
 
 def fnmatch1(name, pat):
        for i in range(len(pat)):
                c = pat[i]
                if c = '*':
-                       restpat = pat[i+1:]
-                       if '*' in restpat or '?' in restpat or '[' in restpat:
-                               for i in range(i, len(name)):
-                                       if fnmatch1(name[i:], restpat):
-                                               return 1
-                               return 0
-                       else:
-                               return name[len(name)-len(restpat):] = restpat
+                       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 = '[':
-                       return 0 # XXX
+                       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
+                                       match = (pat[i-2] <= c <= pat[i])
+                                       i = i+1
+                       if match = exclude:
+                               return 0
+                       return fnmatch1(rest, pat[i+1:])
                else:
                        if name[i:i+1] <> c:
                                return 0