| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | """Filename matching with shell patterns.
 | 
					
						
							| 
									
										
										
										
											1992-01-12 23:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | fnmatch(FILENAME, PATTERN) matches according to the local convention. | 
					
						
							|  |  |  | fnmatchcase(FILENAME, PATTERN) always takes case in account. | 
					
						
							| 
									
										
										
										
											1992-01-12 23:29:29 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | The functions operate by translating the pattern into a regular | 
					
						
							|  |  |  | expression.  They cache the compiled regular expressions for speed. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The function translate(PATTERN) returns a regular expression | 
					
						
							|  |  |  | corresponding to PATTERN.  (It does not compile it.) | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1997-10-22 21:00:49 +00:00
										 |  |  | import re | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2003-07-13 16:06:26 +00:00
										 |  |  | __all__ = ["filter", "fnmatch","fnmatchcase","translate"] | 
					
						
							| 
									
										
										
										
											2001-01-20 23:34:12 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | _cache = {} | 
					
						
							| 
									
										
										
										
											1991-01-01 18:11:14 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | def fnmatch(name, pat): | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |     """Test whether FILENAME matches PATTERN.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     Patterns are Unix shell style: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     *       matches everything | 
					
						
							|  |  |  |     ?       matches any single character | 
					
						
							|  |  |  |     [seq]   matches any character in seq | 
					
						
							|  |  |  |     [!seq]  matches any char not in seq | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     An initial period in FILENAME is not special. | 
					
						
							|  |  |  |     Both FILENAME and PATTERN are first case-normalized | 
					
						
							|  |  |  |     if the operating system requires it. | 
					
						
							|  |  |  |     If you don't want this, use fnmatchcase(FILENAME, PATTERN). | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     import os | 
					
						
							|  |  |  |     name = os.path.normcase(name) | 
					
						
							|  |  |  |     pat = os.path.normcase(pat) | 
					
						
							|  |  |  |     return fnmatchcase(name, pat) | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2001-06-06 06:24:38 +00:00
										 |  |  | def filter(names, pat): | 
					
						
							|  |  |  |     """Return the subset of the list NAMES that match PAT""" | 
					
						
							|  |  |  |     import os,posixpath | 
					
						
							|  |  |  |     result=[] | 
					
						
							|  |  |  |     pat=os.path.normcase(pat) | 
					
						
							| 
									
										
										
										
											2002-06-01 14:18:47 +00:00
										 |  |  |     if not pat in _cache: | 
					
						
							| 
									
										
										
										
											2001-06-06 06:24:38 +00:00
										 |  |  |         res = translate(pat) | 
					
						
							|  |  |  |         _cache[pat] = re.compile(res) | 
					
						
							|  |  |  |     match=_cache[pat].match | 
					
						
							|  |  |  |     if os.path is posixpath: | 
					
						
							|  |  |  |         # normcase on posix is NOP. Optimize it away from the loop. | 
					
						
							|  |  |  |         for name in names: | 
					
						
							|  |  |  |             if match(name): | 
					
						
							|  |  |  |                 result.append(name) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         for name in names: | 
					
						
							|  |  |  |             if match(os.path.normcase(name)): | 
					
						
							|  |  |  |                 result.append(name) | 
					
						
							|  |  |  |     return result | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											1995-01-27 02:41:45 +00:00
										 |  |  | def fnmatchcase(name, pat): | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |     """Test whether FILENAME matches PATTERN, including case.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     This is a version of fnmatch() which doesn't case-normalize | 
					
						
							|  |  |  |     its arguments. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2002-06-01 14:18:47 +00:00
										 |  |  |     if not pat in _cache: | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |         res = translate(pat) | 
					
						
							|  |  |  |         _cache[pat] = re.compile(res) | 
					
						
							|  |  |  |     return _cache[pat].match(name) is not None | 
					
						
							| 
									
										
										
										
											1991-01-01 18:11:14 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											1992-01-12 23:29:29 +00:00
										 |  |  | def translate(pat): | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |     """Translate a shell PATTERN to a regular expression.
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     There is no way to quote meta-characters. | 
					
						
							|  |  |  |     """
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     i, n = 0, len(pat) | 
					
						
							|  |  |  |     res = '' | 
					
						
							|  |  |  |     while i < n: | 
					
						
							|  |  |  |         c = pat[i] | 
					
						
							|  |  |  |         i = i+1 | 
					
						
							|  |  |  |         if c == '*': | 
					
						
							|  |  |  |             res = res + '.*' | 
					
						
							|  |  |  |         elif c == '?': | 
					
						
							|  |  |  |             res = res + '.' | 
					
						
							|  |  |  |         elif c == '[': | 
					
						
							|  |  |  |             j = i | 
					
						
							|  |  |  |             if j < n and pat[j] == '!': | 
					
						
							|  |  |  |                 j = j+1 | 
					
						
							|  |  |  |             if j < n and pat[j] == ']': | 
					
						
							|  |  |  |                 j = j+1 | 
					
						
							|  |  |  |             while j < n and pat[j] != ']': | 
					
						
							|  |  |  |                 j = j+1 | 
					
						
							|  |  |  |             if j >= n: | 
					
						
							|  |  |  |                 res = res + '\\[' | 
					
						
							|  |  |  |             else: | 
					
						
							| 
									
										
										
										
											2001-03-21 18:05:48 +00:00
										 |  |  |                 stuff = pat[i:j].replace('\\','\\\\') | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |                 i = j+1 | 
					
						
							|  |  |  |                 if stuff[0] == '!': | 
					
						
							| 
									
										
										
										
											2001-03-21 18:05:48 +00:00
										 |  |  |                     stuff = '^' + stuff[1:] | 
					
						
							|  |  |  |                 elif stuff[0] == '^': | 
					
						
							|  |  |  |                     stuff = '\\' + stuff | 
					
						
							|  |  |  |                 res = '%s[%s]' % (res, stuff) | 
					
						
							| 
									
										
										
										
											2001-01-14 23:36:06 +00:00
										 |  |  |         else: | 
					
						
							|  |  |  |             res = res + re.escape(c) | 
					
						
							| 
									
										
										
										
											2009-08-16 18:52:58 +00:00
										 |  |  |     return res + '\Z(?ms)' |