LEFT | RIGHT |
1 """Filename matching with shell patterns. | 1 """Filename matching with shell patterns. |
2 | 2 |
3 fnmatch(FILENAME, PATTERN) matches according to the local convention. | 3 fnmatch(FILENAME, PATTERN) matches according to the local convention. |
4 fnmatchcase(FILENAME, PATTERN) always takes case in account. | 4 fnmatchcase(FILENAME, PATTERN) always takes case in account. |
5 | 5 |
6 The functions operate by translating the pattern into a regular | 6 The functions operate by translating the pattern into a regular |
7 expression. They cache the compiled regular expressions for speed. | 7 expression. They cache the compiled regular expressions for speed. |
8 | 8 |
9 The function translate(PATTERN) returns a regular expression | 9 The function translate(PATTERN) returns a regular expression |
10 corresponding to PATTERN. (It does not compile it.) | 10 corresponding to PATTERN. (It does not compile it.) |
(...skipping 20 matching lines...) Expand all Loading... |
31 if the operating system requires it. | 31 if the operating system requires it. |
32 If you don't want this, use fnmatchcase(FILENAME, PATTERN). | 32 If you don't want this, use fnmatchcase(FILENAME, PATTERN). |
33 """ | 33 """ |
34 | 34 |
35 import os | 35 import os |
36 name = os.path.normcase(name) | 36 name = os.path.normcase(name) |
37 pat = os.path.normcase(pat) | 37 pat = os.path.normcase(pat) |
38 return fnmatchcase(name, pat) | 38 return fnmatchcase(name, pat) |
39 | 39 |
40 def _compile_pattern(pat): | 40 def _compile_pattern(pat): |
41 if not pat in _cache: | 41 regex = _cache.get(pat) |
| 42 if regex is None: |
42 if isinstance(pat, bytes): | 43 if isinstance(pat, bytes): |
43 pat_str = str(pat, 'ISO-8859-1') | 44 pat_str = str(pat, 'ISO-8859-1') |
44 res_str = translate(pat_str) | 45 res_str = translate(pat_str) |
45 res = res_str.encode('ISO-8859-1') | 46 res = bytes(res_str, 'ISO-8859-1') |
46 else: | 47 else: |
47 res = translate(pat) | 48 res = translate(pat) |
48 _cache[pat] = re.compile(res) | 49 _cache[pat] = regex = re.compile(res) |
49 return _cache[pat].match | 50 return regex.match |
50 | 51 |
51 def filter(names, pat): | 52 def filter(names, pat): |
52 """Return the subset of the list NAMES that match PAT""" | 53 """Return the subset of the list NAMES that match PAT""" |
53 import os,posixpath | 54 import os,posixpath |
54 result=[] | 55 result = [] |
55 pat=os.path.normcase(pat) | 56 pat = os.path.normcase(pat) |
56 match = _compile_pattern(pat) | 57 match = _compile_pattern(pat) |
57 if os.path is posixpath: | 58 if os.path is posixpath: |
58 # normcase on posix is NOP. Optimize it away from the loop. | 59 # normcase on posix is NOP. Optimize it away from the loop. |
59 for name in names: | 60 for name in names: |
60 if match(name): | 61 if match(name): |
61 result.append(name) | 62 result.append(name) |
62 else: | 63 else: |
63 for name in names: | 64 for name in names: |
64 if match(os.path.normcase(name)): | 65 if match(os.path.normcase(name)): |
65 result.append(name) | 66 result.append(name) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
104 stuff = pat[i:j].replace('\\','\\\\') | 105 stuff = pat[i:j].replace('\\','\\\\') |
105 i = j+1 | 106 i = j+1 |
106 if stuff[0] == '!': | 107 if stuff[0] == '!': |
107 stuff = '^' + stuff[1:] | 108 stuff = '^' + stuff[1:] |
108 elif stuff[0] == '^': | 109 elif stuff[0] == '^': |
109 stuff = '\\' + stuff | 110 stuff = '\\' + stuff |
110 res = '%s[%s]' % (res, stuff) | 111 res = '%s[%s]' % (res, stuff) |
111 else: | 112 else: |
112 res = res + re.escape(c) | 113 res = res + re.escape(c) |
113 return res + "$" | 114 return res + "$" |
LEFT | RIGHT |