0001 """Filename matching with shell patterns. 0002 0003 fnmatch(FILENAME, PATTERN) matches according to the local convention. 0004 fnmatchcase(FILENAME, PATTERN) always takes case in account. 0005 0006 The functions operate by translating the pattern into a regular 0007 expression. They cache the compiled regular expressions for speed. 0008 0009 The function translate(PATTERN) returns a regular expression 0010 corresponding to PATTERN. (It does not compile it.) 0011 """ 0012 0013 import re 0014 0015 __all__ = ["filter", "fnmatch","fnmatchcase","translate"] 0016 0017 _cache = {} 0018 0019 def fnmatch(name, pat): 0020 """Test whether FILENAME matches PATTERN. 0021 0022 Patterns are Unix shell style: 0023 0024 * matches everything 0025 ? matches any single character 0026 [seq] matches any character in seq 0027 [!seq] matches any char not in seq 0028 0029 An initial period in FILENAME is not special. 0030 Both FILENAME and PATTERN are first case-normalized 0031 if the operating system requires it. 0032 If you don't want this, use fnmatchcase(FILENAME, PATTERN). 0033 """ 0034 0035 import os 0036 name = os.path.normcase(name) 0037 pat = os.path.normcase(pat) 0038 return fnmatchcase(name, pat) 0039 0040 def filter(names, pat): 0041 """Return the subset of the list NAMES that match PAT""" 0042 import os,posixpath 0043 result=[] 0044 pat=os.path.normcase(pat) 0045 if not pat in _cache: 0046 res = translate(pat) 0047 _cache[pat] = re.compile(res) 0048 match=_cache[pat].match 0049 if os.path is posixpath: 0050 # normcase on posix is NOP. Optimize it away from the loop. 0051 for name in names: 0052 if match(name): 0053 result.append(name) 0054 else: 0055 for name in names: 0056 if match(os.path.normcase(name)): 0057 result.append(name) 0058 return result 0059 0060 def fnmatchcase(name, pat): 0061 """Test whether FILENAME matches PATTERN, including case. 0062 0063 This is a version of fnmatch() which doesn't case-normalize 0064 its arguments. 0065 """ 0066 0067 if not pat in _cache: 0068 res = translate(pat) 0069 _cache[pat] = re.compile(res) 0070 return _cache[pat].match(name) is not None 0071 0072 def translate(pat): 0073 """Translate a shell PATTERN to a regular expression. 0074 0075 There is no way to quote meta-characters. 0076 """ 0077 0078 i, n = 0, len(pat) 0079 res = '' 0080 while i < n: 0081 c = pat[i] 0082 i = i+1 0083 if c == '*': 0084 res = res + '.*' 0085 elif c == '?': 0086 res = res + '.' 0087 elif c == '[': 0088 j = i 0089 if j < n and pat[j] == '!': 0090 j = j+1 0091 if j < n and pat[j] == ']': 0092 j = j+1 0093 while j < n and pat[j] != ']': 0094 j = j+1 0095 if j >= n: 0096 res = res + '\\[' 0097 else: 0098 stuff = pat[i:j].replace('\\','\\\\') 0099 i = j+1 0100 if stuff[0] == '!': 0101 stuff = '^' + stuff[1:] 0102 elif stuff[0] == '^': 0103 stuff = '\\' + stuff 0104 res = '%s[%s]' % (res, stuff) 0105 else: 0106 res = res + re.escape(c) 0107 return res + "$" 0108
Generated by PyXR 0.9.4