blob: 75d2d6eb43b49514f739eb8e74353bb7f5400ed3 [file] [log] [blame]
Guido van Rossum7e4b2de1995-01-27 02:41:45 +00001"""Filename matching with shell patterns.
Guido van Rossum05e52191992-01-12 23:29:29 +00002
Guido van Rossum7e4b2de1995-01-27 02:41:45 +00003fnmatch(FILENAME, PATTERN) matches according to the local convention.
4fnmatchcase(FILENAME, PATTERN) always takes case in account.
Guido van Rossum05e52191992-01-12 23:29:29 +00005
Guido van Rossum7e4b2de1995-01-27 02:41:45 +00006The functions operate by translating the pattern into a regular
7expression. They cache the compiled regular expressions for speed.
8
9The function translate(PATTERN) returns a regular expression
10corresponding to PATTERN. (It does not compile it.)
11"""
12
Guido van Rossum9694fca1997-10-22 21:00:49 +000013import re
14
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000015_cache = {}
Guido van Rossum762c39e1991-01-01 18:11:14 +000016
Guido van Rossum762c39e1991-01-01 18:11:14 +000017def fnmatch(name, pat):
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000018 """Test whether FILENAME matches PATTERN.
19
20 Patterns are Unix shell style:
21
22 * matches everything
23 ? matches any single character
24 [seq] matches any character in seq
25 [!seq] matches any char not in seq
26
27 An initial period in FILENAME is not special.
28 Both FILENAME and PATTERN are first case-normalized
29 if the operating system requires it.
30 If you don't want this, use fnmatchcase(FILENAME, PATTERN).
31 """
32
33 import os
Guido van Rossum05e52191992-01-12 23:29:29 +000034 name = os.path.normcase(name)
35 pat = os.path.normcase(pat)
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000036 return fnmatchcase(name, pat)
37
38def fnmatchcase(name, pat):
Jeremy Hyltona05e2932000-06-28 14:48:01 +000039 """Test whether FILENAME matches PATTERN, including case.
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000040
41 This is a version of fnmatch() which doesn't case-normalize
42 its arguments.
43 """
44
45 if not _cache.has_key(pat):
Guido van Rossum05e52191992-01-12 23:29:29 +000046 res = translate(pat)
Guido van Rossum9694fca1997-10-22 21:00:49 +000047 _cache[pat] = re.compile(res)
48 return _cache[pat].match(name) is not None
Guido van Rossum762c39e1991-01-01 18:11:14 +000049
Guido van Rossum05e52191992-01-12 23:29:29 +000050def translate(pat):
Guido van Rossum7e4b2de1995-01-27 02:41:45 +000051 """Translate a shell PATTERN to a regular expression.
52
53 There is no way to quote meta-characters.
54 """
55
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000056 i, n = 0, len(pat)
Guido van Rossum05e52191992-01-12 23:29:29 +000057 res = ''
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000058 while i < n:
Guido van Rossum762c39e1991-01-01 18:11:14 +000059 c = pat[i]
Guido van Rossumbdfcfcc1992-01-01 19:35:13 +000060 i = i+1
Guido van Rossum05e52191992-01-12 23:29:29 +000061 if c == '*':
62 res = res + '.*'
63 elif c == '?':
64 res = res + '.'
65 elif c == '[':
66 j = i
67 if j < n and pat[j] == '!':
68 j = j+1
69 if j < n and pat[j] == ']':
70 j = j+1
71 while j < n and pat[j] != ']':
72 j = j+1
73 if j >= n:
74 res = res + '\\['
75 else:
76 stuff = pat[i:j]
77 i = j+1
78 if stuff[0] == '!':
79 stuff = '[^' + stuff[1:] + ']'
80 elif stuff == '^'*len(stuff):
81 stuff = '\\^'
82 else:
83 while stuff[0] == '^':
84 stuff = stuff[1:] + stuff[0]
85 stuff = '[' + stuff + ']'
86 res = res + stuff
Guido van Rossum05e52191992-01-12 23:29:29 +000087 else:
Guido van Rossum9694fca1997-10-22 21:00:49 +000088 res = res + re.escape(c)
89 return res + "$"