79
79
def __call__(self, text):
81
81
self._pat = lazy_regex.lazy_compile(
82
u'|'.join([u'(%s)' % p for p in self._pats]),
82
u'|'.join([u'(%s)' % p for p in self._pats]),
84
84
return self._pat.sub(self._do_sub, text)
86
86
def _do_sub(self, m):
138
138
_sub_fullpath = Replacer()
139
_sub_fullpath.add(r'^RE:.*', _sub_re) # RE:<anything> is a regex
140
_sub_fullpath.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]', _sub_group) # char group
141
_sub_fullpath.add(r'(?:(?<=/)|^)(?:\.?/)+', u'') # canonicalize path
142
_sub_fullpath.add(r'\\.', r'\&') # keep anything backslashed
143
_sub_fullpath.add(r'[(){}|^$+.]', r'\\&') # escape specials
144
_sub_fullpath.add(r'(?:(?<=/)|^)\*\*+/', r'(?:.*/)?') # **/ after ^ or /
145
_sub_fullpath.add(r'\*+', r'[^/]*') # * elsewhere
146
_sub_fullpath.add(r'\?', r'[^/]') # ? everywhere
139
_sub_fullpath.add(r'^RE:.*', _sub_re) # RE:<anything> is a regex
140
_sub_fullpath.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]',
141
_sub_group) # char group
142
_sub_fullpath.add(r'(?:(?<=/)|^)(?:\.?/)+', u'') # canonicalize path
143
_sub_fullpath.add(r'\\.', r'\&') # keep anything backslashed
144
_sub_fullpath.add(r'[(){}|^$+.]', r'\\&') # escape specials
145
_sub_fullpath.add(r'(?:(?<=/)|^)\*\*+/', r'(?:.*/)?') # **/ after ^ or /
146
_sub_fullpath.add(r'\*+', r'[^/]*') # * elsewhere
147
_sub_fullpath.add(r'\?', r'[^/]') # ? everywhere
149
150
_sub_basename = Replacer()
150
_sub_basename.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]', _sub_group) # char group
151
_sub_basename.add(r'\\.', r'\&') # keep anything backslashed
152
_sub_basename.add(r'[(){}|^$+.]', r'\\&') # escape specials
153
_sub_basename.add(r'\*+', r'.*') # * everywhere
154
_sub_basename.add(r'\?', r'.') # ? everywhere
151
_sub_basename.add(r'\[\^?\]?(?:[^][]|\[:[^]]+:\])+\]',
152
_sub_group) # char group
153
_sub_basename.add(r'\\.', r'\&') # keep anything backslashed
154
_sub_basename.add(r'[(){}|^$+.]', r'\\&') # escape specials
155
_sub_basename.add(r'\*+', r'.*') # * everywhere
156
_sub_basename.add(r'\?', r'.') # ? everywhere
157
159
def _sub_extension(pattern):
187
189
# starting with the shortest and going to the longest.
188
190
# As some Python version don't support ordered dicts the list below is
189
191
# used to select inputs for _add_pattern in a specific order.
190
pattern_types = [ "extension", "basename", "fullpath" ]
192
pattern_types = ["extension", "basename", "fullpath"]
194
"translator" : _sub_extension,
195
"prefix" : r'(?:.*/)?(?!.*/)(?:.*\.)'
196
"translator": _sub_extension,
197
"prefix": r'(?:.*/)?(?!.*/)(?:.*\.)'
198
"translator" : _sub_basename,
199
"prefix" : r'(?:.*/)?(?!.*/)'
200
"translator": _sub_basename,
201
"prefix": r'(?:.*/)?(?!.*/)'
202
"translator" : _sub_fullpath,
204
"translator": _sub_fullpath,
217
219
pi = Globster.pattern_info
218
220
for t in Globster.pattern_types:
219
221
self._add_patterns(pattern_lists[t], pi[t]["translator"],
222
224
def _add_patterns(self, patterns, translator, prefix=''):
240
242
for regex, patterns in self._regex_patterns:
241
243
match = regex.match(filename)
243
return patterns[match.lastindex -1]
245
return patterns[match.lastindex - 1]
244
246
except lazy_regex.InvalidPattern as e:
245
247
# We can't show the default e.msg to the user as thats for
246
248
# the combined pattern we sent to regex. Instead we indicate to
280
282
see: globbing.normalize_pattern
283
translator = Globster.pattern_info[Globster.identify(pattern)]["translator"]
285
translator = Globster.pattern_info[Globster.identify(
286
pattern)]["translator"]
284
287
tpattern = '(%s)' % translator(pattern)
286
289
re_obj = lazy_regex.lazy_compile(tpattern, re.UNICODE)
287
re_obj.search("") # force compile
288
except lazy_regex.InvalidPattern as e:
290
re_obj.search("") # force compile
291
except lazy_regex.InvalidPattern:
293
296
class ExceptionGlobster(object):
294
297
"""A Globster that supports exception patterns.
296
299
Exceptions are ignore patterns prefixed with '!'. Exception
297
300
patterns take precedence over regular patterns and cause a
298
301
matching filename to return None from the match() function.
339
343
pat = normalize_pattern(pat)
340
344
t = Globster.identify(pat)
341
345
self._add_patterns([pat], Globster.pattern_info[t]["translator"],
342
Globster.pattern_info[t]["prefix"])
346
Globster.pattern_info[t]["prefix"])
345
349
_slashes = lazy_regex.lazy_compile(r'[\\/]+')
346
352
def normalize_pattern(pattern):
347
353
"""Converts backslashes in path patterns to forward slashes.