source: python/trunk/Lib/fnmatch.py@ 403

Last change on this file since 403 was 391, checked in by dmik, 11 years ago

python: Merge vendor 2.7.6 to trunk.

  • Property svn:eol-style set to native
File size: 3.2 KB
Line 
1"""Filename matching with shell patterns.
2
3fnmatch(FILENAME, PATTERN) matches according to the local convention.
4fnmatchcase(FILENAME, PATTERN) always takes case in account.
5
6The functions operate by translating the pattern into a regular
7expression. They cache the compiled regular expressions for speed.
8
9The function translate(PATTERN) returns a regular expression
10corresponding to PATTERN. (It does not compile it.)
11"""
12
13import re
14
15__all__ = ["filter", "fnmatch", "fnmatchcase", "translate"]
16
17_cache = {}
18_MAXCACHE = 100
19
20def _purge():
21 """Clear the pattern cache"""
22 _cache.clear()
23
24def fnmatch(name, pat):
25 """Test whether FILENAME matches PATTERN.
26
27 Patterns are Unix shell style:
28
29 * matches everything
30 ? matches any single character
31 [seq] matches any character in seq
32 [!seq] matches any char not in seq
33
34 An initial period in FILENAME is not special.
35 Both FILENAME and PATTERN are first case-normalized
36 if the operating system requires it.
37 If you don't want this, use fnmatchcase(FILENAME, PATTERN).
38 """
39
40 import os
41 name = os.path.normcase(name)
42 pat = os.path.normcase(pat)
43 return fnmatchcase(name, pat)
44
45def filter(names, pat):
46 """Return the subset of the list NAMES that match PAT"""
47 import os,posixpath
48 result=[]
49 pat=os.path.normcase(pat)
50 if not pat in _cache:
51 res = translate(pat)
52 if len(_cache) >= _MAXCACHE:
53 _cache.clear()
54 _cache[pat] = re.compile(res)
55 match=_cache[pat].match
56 if os.path is posixpath:
57 # normcase on posix is NOP. Optimize it away from the loop.
58 for name in names:
59 if match(name):
60 result.append(name)
61 else:
62 for name in names:
63 if match(os.path.normcase(name)):
64 result.append(name)
65 return result
66
67def fnmatchcase(name, pat):
68 """Test whether FILENAME matches PATTERN, including case.
69
70 This is a version of fnmatch() which doesn't case-normalize
71 its arguments.
72 """
73
74 if not pat in _cache:
75 res = translate(pat)
76 if len(_cache) >= _MAXCACHE:
77 _cache.clear()
78 _cache[pat] = re.compile(res)
79 return _cache[pat].match(name) is not None
80
81def translate(pat):
82 """Translate a shell PATTERN to a regular expression.
83
84 There is no way to quote meta-characters.
85 """
86
87 i, n = 0, len(pat)
88 res = ''
89 while i < n:
90 c = pat[i]
91 i = i+1
92 if c == '*':
93 res = res + '.*'
94 elif c == '?':
95 res = res + '.'
96 elif c == '[':
97 j = i
98 if j < n and pat[j] == '!':
99 j = j+1
100 if j < n and pat[j] == ']':
101 j = j+1
102 while j < n and pat[j] != ']':
103 j = j+1
104 if j >= n:
105 res = res + '\\['
106 else:
107 stuff = pat[i:j].replace('\\','\\\\')
108 i = j+1
109 if stuff[0] == '!':
110 stuff = '^' + stuff[1:]
111 elif stuff[0] == '^':
112 stuff = '\\' + stuff
113 res = '%s[%s]' % (res, stuff)
114 else:
115 res = res + re.escape(c)
116 return res + '\Z(?ms)'
Note: See TracBrowser for help on using the repository browser.