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)