Index: django/core/urlresolvers.py
===================================================================
--- django/core/urlresolvers.py	(revision 7396)
+++ django/core/urlresolvers.py	(working copy)
@@ -84,21 +84,39 @@
 
     Raises NoReverseMatch if the args/kwargs aren't valid for the regex.
     """
-    # TODO: Handle nested parenthesis in the following regex.
-    result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), regex.pattern)
-    return result.replace('^', '').replace('$', '')
+    url = grouped = ''
+    level = 0
+    match_checker = MatchChecker(args, kwargs)
 
+    for c in regex.pattern:
+        if c == '(':
+            level += 1
+            if level == 1:
+                continue
+        elif c == ')':
+            level -= 1
+            if level == 0:
+                url += match_checker(grouped)
+                grouped = ''
+                continue
+        
+        if level == 0:
+            url += c
+        else:
+            grouped += c
+
+    return url.replace('^', '').replace('$', '')
+
 class MatchChecker(object):
     "Class used in reverse RegexURLPattern lookup."
     def __init__(self, args, kwargs):
         self.args, self.kwargs = args, kwargs
         self.current_arg = 0
 
-    def __call__(self, match_obj):
-        # match_obj.group(1) is the contents of the parenthesis.
+    def __call__(self, grouped):
+        # grouped is the contents of the outer parenthesis.
         # First we need to figure out whether it's a named or unnamed group.
         #
-        grouped = match_obj.group(1)
         m = re.search(r'^\?P<(\w+)>(.*?)$', grouped, re.UNICODE)
         if m: # If this was a named group...
             # m.group(1) is the name of the group
@@ -115,7 +133,7 @@
                     # The arg wasn't passed in.
                     raise NoReverseMatch('Not enough positional arguments passed in')
             test_regex = m.group(2)
-        else: # Otherwise, this was a positional (unnamed) group.
+        elif not re.match(r'^\?', grouped, re.UNICODE): # If this was a positional (unnamed) group.
             try:
                 value = self.args[self.current_arg]
                 self.current_arg += 1
@@ -123,6 +141,8 @@
                 # The arg wasn't passed in.
                 raise NoReverseMatch('Not enough positional arguments passed in')
             test_regex = grouped
+        else: # Otherwise, it was a not-matching, look-ahead, or -behind group.
+            return u''
         # Note we're using re.match here on purpose because the start of
         # to string needs to match.
         if not re.match(test_regex + '$', force_unicode(value), re.UNICODE):
