Ticket #6934: support-for-more-flexible-url-regex-patterns.patch
File support-for-more-flexible-url-regex-patterns.patch, 2.6 KB (added by , 17 years ago) |
---|
-
django/core/urlresolvers.py
84 84 85 85 Raises NoReverseMatch if the args/kwargs aren't valid for the regex. 86 86 """ 87 # TODO: Handle nested parenthesis in the following regex.88 result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), regex.pattern)89 return result.replace('^', '').replace('$', '')87 url = grouped = '' 88 level = 0 89 match_checker = MatchChecker(args, kwargs) 90 90 91 for c in regex.pattern: 92 if c == '(': 93 level += 1 94 if level == 1: 95 continue 96 elif c == ')': 97 level -= 1 98 if level == 0: 99 url += match_checker(grouped) 100 grouped = '' 101 continue 102 103 if level == 0: 104 url += c 105 else: 106 grouped += c 107 108 return url.replace('^', '').replace('$', '') 109 91 110 class MatchChecker(object): 92 111 "Class used in reverse RegexURLPattern lookup." 93 112 def __init__(self, args, kwargs): 94 113 self.args, self.kwargs = args, kwargs 95 114 self.current_arg = 0 96 115 97 def __call__(self, match_obj):98 # match_obj.group(1) is the contents of theparenthesis.116 def __call__(self, grouped): 117 # grouped is the contents of the outer parenthesis. 99 118 # First we need to figure out whether it's a named or unnamed group. 100 119 # 101 grouped = match_obj.group(1)102 120 m = re.search(r'^\?P<(\w+)>(.*?)$', grouped, re.UNICODE) 103 121 if m: # If this was a named group... 104 122 # m.group(1) is the name of the group … … 115 133 # The arg wasn't passed in. 116 134 raise NoReverseMatch('Not enough positional arguments passed in') 117 135 test_regex = m.group(2) 118 el se: # Otherwise,this was a positional (unnamed) group.136 elif not re.match(r'^\?', grouped, re.UNICODE): # If this was a positional (unnamed) group. 119 137 try: 120 138 value = self.args[self.current_arg] 121 139 self.current_arg += 1 … … 123 141 # The arg wasn't passed in. 124 142 raise NoReverseMatch('Not enough positional arguments passed in') 125 143 test_regex = grouped 144 else: # Otherwise, it was a not-matching, look-ahead, or -behind group. 145 return u'' 126 146 # Note we're using re.match here on purpose because the start of 127 147 # to string needs to match. 128 148 if not re.match(test_regex + '$', force_unicode(value), re.UNICODE):