|
2260
|
1 """Filename matching with shell patterns.
|
|
|
2
|
|
|
3 fnmatch(FILENAME, PATTERN) matches according to the local convention.
|
|
|
4 fnmatchcase(FILENAME, PATTERN) always takes case in account.
|
|
573
|
5
|
|
2260
|
6 The functions operate by translating the pattern into a regular
|
|
|
7 expression. They cache the compiled regular expressions for speed.
|
|
573
|
8
|
|
2260
|
9 The function translate(PATTERN) returns a regular expression
|
|
|
10 corresponding to PATTERN. (It does not compile it.)
|
|
|
11 """
|
|
|
12
|
|
|
13 _cache = {}
|
|
106
|
14
|
|
|
15 def fnmatch(name, pat):
|
|
2260
|
16 """Test whether FILENAME matches PATTERN.
|
|
|
17
|
|
|
18 Patterns are Unix shell style:
|
|
|
19
|
|
|
20 * matches everything
|
|
|
21 ? matches any single character
|
|
|
22 [seq] matches any character in seq
|
|
|
23 [!seq] matches any char not in seq
|
|
|
24
|
|
|
25 An initial period in FILENAME is not special.
|
|
|
26 Both FILENAME and PATTERN are first case-normalized
|
|
|
27 if the operating system requires it.
|
|
|
28 If you don't want this, use fnmatchcase(FILENAME, PATTERN).
|
|
|
29 """
|
|
|
30
|
|
|
31 import os
|
|
573
|
32 name = os.path.normcase(name)
|
|
|
33 pat = os.path.normcase(pat)
|
|
2260
|
34 return fnmatchcase(name, pat)
|
|
|
35
|
|
|
36 def fnmatchcase(name, pat):
|
|
|
37 """Test wheter FILENAME matches PATTERN, including case.
|
|
|
38
|
|
|
39 This is a version of fnmatch() which doesn't case-normalize
|
|
|
40 its arguments.
|
|
|
41 """
|
|
|
42
|
|
|
43 if not _cache.has_key(pat):
|
|
573
|
44 res = translate(pat)
|
|
2260
|
45 import regex
|
|
573
|
46 save_syntax = regex.set_syntax(0)
|
|
2260
|
47 _cache[pat] = regex.compile(res)
|
|
573
|
48 save_syntax = regex.set_syntax(save_syntax)
|
|
2260
|
49 return _cache[pat].match(name) == len(name)
|
|
106
|
50
|
|
573
|
51 def translate(pat):
|
|
2260
|
52 """Translate a shell PATTERN to a regular expression.
|
|
|
53
|
|
|
54 There is no way to quote meta-characters.
|
|
|
55 """
|
|
|
56
|
|
559
|
57 i, n = 0, len(pat)
|
|
573
|
58 res = ''
|
|
559
|
59 while i < n:
|
|
106
|
60 c = pat[i]
|
|
573
|
61 i = i+1
|
|
559
|
62 if c == '*':
|
|
573
|
63 res = res + '.*'
|
|
559
|
64 elif c == '?':
|
|
573
|
65 res = res + '.'
|
|
559
|
66 elif c == '[':
|
|
573
|
67 j = i
|
|
|
68 if j < n and pat[j] == '!':
|
|
|
69 j = j+1
|
|
|
70 if j < n and pat[j] == ']':
|
|
|
71 j = j+1
|
|
|
72 while j < n and pat[j] != ']':
|
|
|
73 j = j+1
|
|
|
74 if j >= n:
|
|
|
75 res = res + '\\['
|
|
|
76 else:
|
|
|
77 stuff = pat[i:j]
|
|
|
78 i = j+1
|
|
|
79 if stuff[0] == '!':
|
|
|
80 stuff = '[^' + stuff[1:] + ']'
|
|
|
81 elif stuff == '^'*len(stuff):
|
|
|
82 stuff = '\\^'
|
|
|
83 else:
|
|
|
84 while stuff[0] == '^':
|
|
|
85 stuff = stuff[1:] + stuff[0]
|
|
|
86 stuff = '[' + stuff + ']'
|
|
|
87 res = res + stuff
|
|
|
88 elif c in '\\.+^$':
|
|
|
89 res = res + ('\\' + c)
|
|
106
|
90 else:
|
|
573
|
91 res = res + c
|
|
106
|
92 return res
|