1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 """ This module provides support for Ant-style wildcards,
21 which are not the same as regular expressions (which are documented in the re module).
22 """
23 import os.path
24 import pathaddition.relative
25 import logging
26 import fnmatch
27 import re
28 import sys
29
30 _logger = logging.getLogger('path.match')
31
32
33
34 _cache = {}
35
36 -def ant_match(name, pattern, casesensitive=True):
37 """Check if name matches pattern (Ant-style wildcards).
38 """
39 _logger.debug("ant_match: path='%s' pattern='%s'" % (name, pattern))
40 if pattern.endswith('/') or pattern.endswith('\\'):
41 pattern = pattern + '**'
42 _logger.debug("ant_match: pattern ending with / or \ pattern='%s'" % (pattern))
43 name = os.path.normpath(name)
44 pattern = os.path.normpath(pattern)
45 name = name.replace('/', os.sep)
46 name = name.replace('\\', os.sep)
47 pattern = pattern.replace('/', os.sep)
48 pattern = pattern.replace('\\', os.sep)
49 _logger.debug("ant_match:normpath: path='%s' pattern='%s'" % (name, pattern))
50
51 if not _cache.has_key(pattern):
52 res = translate(pattern)
53 _logger.debug("ant_match: regexp=%s" % (res))
54 if sys.platform == "win32" or not casesensitive:
55 _cache[pattern] = re.compile(res, re.I)
56 else:
57 _cache[pattern] = re.compile(res)
58 return _cache[pattern].match(name) is not None
59
60
62 """Translate a Ant-style PATTERN to a regular expression.
63
64 There is no way to quote meta-characters.
65 """
66
67 i, n = 0, len(pat)
68 res = ''
69 while i < n:
70 c = pat[i]
71 i = i+1
72 if c == '*':
73
74 if i < len(pat) and pat[i] == '*':
75 res = res + "(?:(?:^|%s)[^%s]+)*(?:^|%s|$)" % (os.sep.replace('\\','\\\\'), os.sep.replace('\\','\\\\'), os.sep.replace('\\','\\\\'))
76 i = i+1
77
78 if i < len(pat) and pat[i] == os.sep:
79 i = i+1
80 else:
81 res = res + '[^%s]*' % os.sep.replace('\\','\\\\')
82 elif c == '?':
83 res = res + '[^%s]*' % os.sep.replace('\\','\\\\')
84 elif c == '[':
85 j = i
86 if j < n and pat[j] == '!':
87 j = j+1
88 if j < n and pat[j] == ']':
89 j = j+1
90 while j < n and pat[j] != ']':
91 j = j+1
92 if j >= n:
93 res = res + '\\['
94 else:
95 stuff = pat[i:j].replace('\\','\\\\')
96 i = j+1
97 if stuff[0] == '!':
98 stuff = '^' + stuff[1:]
99 elif stuff[0] == '^':
100 stuff = '\\' + stuff
101 res = '%s[%s]' % (res, stuff)
102 else:
103
104 if c == os.sep and i+2 <= len(pat) and pat[i] == "*" and pat[i+1] == "*":
105
106 pass
107 else:
108 res = res + re.escape(c)
109 return res + "$"
110