"""Filename matching with shell patterns.
fnmatch(FILENAME, PATTERN) matches according to the local convention.
fnmatchcase(FILENAME, PATTERN) always takes case in account.
The functions operate by translating the pattern into a regular
expression. They cache the compiled regular expressions for speed.
The function translate(PATTERN) returns a regular expression
corresponding to PATTERN. (It does not compile it.)
__all__
= ["filter", "fnmatch","fnmatchcase","translate"]
"""Test whether FILENAME matches PATTERN.
Patterns are Unix shell style:
? matches any single character
[seq] matches any character in seq
[!seq] matches any char not in seq
An initial period in FILENAME is not special.
Both FILENAME and PATTERN are first case-normalized
if the operating system requires it.
If you don't want this, use fnmatchcase(FILENAME, PATTERN).
name
= os
.path
.normcase(name
)
pat
= os
.path
.normcase(pat
)
return fnmatchcase(name
, pat
)
"""Return the subset of the list NAMES that match PAT"""
pat
=os
.path
.normcase(pat
)
_cache
[pat
] = re
.compile(res
)
# normcase on posix is NOP. Optimize it away from the loop.
if match(os
.path
.normcase(name
)):
def fnmatchcase(name
, pat
):
"""Test whether FILENAME matches PATTERN, including case.
This is a version of fnmatch() which doesn't case-normalize
_cache
[pat
] = re
.compile(res
)
return _cache
[pat
].match(name
) is not None
"""Translate a shell PATTERN to a regular expression.
There is no way to quote meta-characters.
if j
< n
and pat
[j
] == '!':
if j
< n
and pat
[j
] == ']':
while j
< n
and pat
[j
] != ']':
stuff
= pat
[i
:j
].replace('\\','\\\\')
res
= '%s[%s]' % (res
, stuff
)