Rewritten using regex.
diff --git a/Lib/fnmatch.py b/Lib/fnmatch.py
index 549e0e7..c30aaca 100644
--- a/Lib/fnmatch.py
+++ b/Lib/fnmatch.py
@@ -1,77 +1,57 @@
 # module 'fnmatch' -- filename matching with shell patterns
+# This version translates the pattern to a regular expression
+# and moreover caches the expressions.
+
+import os
+import regex
+
+cache = {}
 
 def fnmatch(name, pat):
-	#
-	# Check for simple case: no special characters
-	#
-	if not ('*' in pat or '?' in pat or '[' in pat):
-		return name == pat
-	#
-	# Check for common cases: *suffix and prefix*
-	#
-	if pat[0] == '*':
-		p1 = pat[1:]
-		if not ('*' in p1 or '?' in p1 or '[' in p1):
-			start = len(name) - len(p1)
-			return start >= 0 and name[start:] == p1
-	elif pat[-1:] == '*':
-		p1 = pat[:-1]
-		if not ('*' in p1 or '?' in p1 or '[' in p1):
-			return name[:len(p1)] == p1
-	#
-	# General case
-	#
-	return fnmatch1(name, pat)
+	name = os.path.normcase(name)
+	pat = os.path.normcase(pat)
+	if not cache.has_key(pat):
+		res = translate(pat)
+		save_syntax = regex.set_syntax(0)
+		cache[pat] = regex.compile(res)
+		save_syntax = regex.set_syntax(save_syntax)
+	return cache[pat].match(name) == len(name)
 
-def fnmatch1(name, pat):
+def translate(pat):
 	i, n = 0, len(pat)
+	res = ''
 	while i < n:
 		c = pat[i]
-		if c == '*':
-			p1 = pat[i+1:]
-			if not ('*' in p1 or '?' in p1 or '[' in p1):
-				start = len(name) - len(p1)
-				return start >= 0 and name[start:] == p1
-			for i in range(i, len(name) + 1):
-				if fnmatch1(name[i:], p1):
-					return 1
-			return 0
-		elif c == '?':
-			if len(name) <= i : return 0
-		elif c == '[':
-			c, rest = name[i], name[i+1:]
-			i, n = i+1, len(pat) - 1
-			match = 0
-			exclude = 0
-			if i < n and pat[i] == '!':
-				exclude = 1
-				i = i+1
-			while i < n:
-				if pat[i] == c: match = 1
-				i = i+1
-				if i >= n or pat[i] == ']':
-					break
-				if pat[i] == '-':
-					i = i+1
-					if i >= n or pat[i] == ']':
-						break
-					if pat[i-2] <= c <= pat[i]:
-						match = 1
-					i = i+1
-					if i >= n or pat[i] == ']':
-						break
-			if match == exclude:
-				return 0
-			return fnmatch1(rest, pat[i+1:])
-		else:
-			if name[i:i+1] <> c:
-				return 0
 		i = i+1
-	# We don't get here if the pattern contained * or [...]
-	return i >= len(name)
-
-def fnmatchlist(names, pat):
-	res = []
-	for name in names:
-		if fnmatch(name, pat): res.append(name)
+		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:
+				stuff = pat[i:j]
+				i = j+1
+				if stuff[0] == '!':
+					stuff = '[^' + stuff[1:] + ']'
+				elif stuff == '^'*len(stuff):
+					stuff = '\\^'
+				else:
+					while stuff[0] == '^':
+						stuff = stuff[1:] + stuff[0]
+					stuff = '[' + stuff + ']'
+				res = res + stuff
+		elif c in '\\.+^$':
+			res = res + ('\\' + c)
+		else:
+			res = res + c
+	print 'translate(' + `pat` + ') == ' + `res`
 	return res