1 """Filename matching with shell patterns.
3 fnmatch(FILENAME, PATTERN) matches according to the local convention.
4 fnmatchcase(FILENAME, PATTERN) always takes case in account.
6 The functions operate by translating the pattern into a regular
7 expression. They cache the compiled regular expressions for speed.
9 The function translate(PATTERN) returns a regular expression
10 corresponding to PATTERN. (It does not compile it.)
15 __all__
= ["filter", "fnmatch","fnmatchcase","translate"]
19 def fnmatch(name
, pat
):
20 """Test whether FILENAME matches PATTERN.
22 Patterns are Unix shell style:
25 ? matches any single character
26 [seq] matches any character in seq
27 [!seq] matches any char not in seq
29 An initial period in FILENAME is not special.
30 Both FILENAME and PATTERN are first case-normalized
31 if the operating system requires it.
32 If you don't want this, use fnmatchcase(FILENAME, PATTERN).
36 name
= os
.path
.normcase(name
)
37 pat
= os
.path
.normcase(pat
)
38 return fnmatchcase(name
, pat
)
40 def filter(names
, pat
):
41 """Return the subset of the list NAMES that match PAT"""
44 pat
=os
.path
.normcase(pat
)
47 _cache
[pat
] = re
.compile(res
)
48 match
=_cache
[pat
].match
49 if os
.path
is posixpath
:
50 # normcase on posix is NOP. Optimize it away from the loop.
56 if match(os
.path
.normcase(name
)):
60 def fnmatchcase(name
, pat
):
61 """Test whether FILENAME matches PATTERN, including case.
63 This is a version of fnmatch() which doesn't case-normalize
69 _cache
[pat
] = re
.compile(res
)
70 return _cache
[pat
].match(name
) is not None
73 """Translate a shell PATTERN to a regular expression.
75 There is no way to quote meta-characters.
89 if j
< n
and pat
[j
] == '!':
91 if j
< n
and pat
[j
] == ']':
93 while j
< n
and pat
[j
] != ']':
98 stuff
= pat
[i
:j
].replace('\\','\\\\')
101 stuff
= '^' + stuff
[1:]
102 elif stuff
[0] == '^':
104 res
= '%s[%s]' % (res
, stuff
)
106 res
= res
+ re
.escape(c
)