Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 05e5219

Browse files
committed
Rewritten using regex.
1 parent 9542c58 commit 05e5219

1 file changed

Lines changed: 45 additions & 65 deletions

File tree

Lib/fnmatch.py

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,77 +1,57 @@
11
# module 'fnmatch' -- filename matching with shell patterns
2+
# This version translates the pattern to a regular expression
3+
# and moreover caches the expressions.
4+
5+
import os
6+
import regex
7+
8+
cache = {}
29

310
def fnmatch(name, pat):
4-
#
5-
# Check for simple case: no special characters
6-
#
7-
if not ('*' in pat or '?' in pat or '[' in pat):
8-
return name == pat
9-
#
10-
# Check for common cases: *suffix and prefix*
11-
#
12-
if pat[0] == '*':
13-
p1 = pat[1:]
14-
if not ('*' in p1 or '?' in p1 or '[' in p1):
15-
start = len(name) - len(p1)
16-
return start >= 0 and name[start:] == p1
17-
elif pat[-1:] == '*':
18-
p1 = pat[:-1]
19-
if not ('*' in p1 or '?' in p1 or '[' in p1):
20-
return name[:len(p1)] == p1
21-
#
22-
# General case
23-
#
24-
return fnmatch1(name, pat)
11+
name = os.path.normcase(name)
12+
pat = os.path.normcase(pat)
13+
if not cache.has_key(pat):
14+
res = translate(pat)
15+
save_syntax = regex.set_syntax(0)
16+
cache[pat] = regex.compile(res)
17+
save_syntax = regex.set_syntax(save_syntax)
18+
return cache[pat].match(name) == len(name)
2519

26-
def fnmatch1(name, pat):
20+
def translate(pat):
2721
i, n = 0, len(pat)
22+
res = ''
2823
while i < n:
2924
c = pat[i]
25+
i = i+1
3026
if c == '*':
31-
p1 = pat[i+1:]
32-
if not ('*' in p1 or '?' in p1 or '[' in p1):
33-
start = len(name) - len(p1)
34-
return start >= 0 and name[start:] == p1
35-
for i in range(i, len(name) + 1):
36-
if fnmatch1(name[i:], p1):
37-
return 1
38-
return 0
27+
res = res + '.*'
3928
elif c == '?':
40-
if len(name) <= i : return 0
29+
res = res + '.'
4130
elif c == '[':
42-
c, rest = name[i], name[i+1:]
43-
i, n = i+1, len(pat) - 1
44-
match = 0
45-
exclude = 0
46-
if i < n and pat[i] == '!':
47-
exclude = 1
48-
i = i+1
49-
while i < n:
50-
if pat[i] == c: match = 1
51-
i = i+1
52-
if i >= n or pat[i] == ']':
53-
break
54-
if pat[i] == '-':
55-
i = i+1
56-
if i >= n or pat[i] == ']':
57-
break
58-
if pat[i-2] <= c <= pat[i]:
59-
match = 1
60-
i = i+1
61-
if i >= n or pat[i] == ']':
62-
break
63-
if match == exclude:
64-
return 0
65-
return fnmatch1(rest, pat[i+1:])
31+
j = i
32+
if j < n and pat[j] == '!':
33+
j = j+1
34+
if j < n and pat[j] == ']':
35+
j = j+1
36+
while j < n and pat[j] != ']':
37+
j = j+1
38+
if j >= n:
39+
res = res + '\\['
40+
else:
41+
stuff = pat[i:j]
42+
i = j+1
43+
if stuff[0] == '!':
44+
stuff = '[^' + stuff[1:] + ']'
45+
elif stuff == '^'*len(stuff):
46+
stuff = '\\^'
47+
else:
48+
while stuff[0] == '^':
49+
stuff = stuff[1:] + stuff[0]
50+
stuff = '[' + stuff + ']'
51+
res = res + stuff
52+
elif c in '\\.+^$':
53+
res = res + ('\\' + c)
6654
else:
67-
if name[i:i+1] <> c:
68-
return 0
69-
i = i+1
70-
# We don't get here if the pattern contained * or [...]
71-
return i >= len(name)
72-
73-
def fnmatchlist(names, pat):
74-
res = []
75-
for name in names:
76-
if fnmatch(name, pat): res.append(name)
55+
res = res + c
56+
print 'translate(' + `pat` + ') == ' + `res`
7757
return res

0 commit comments

Comments
 (0)