| 42 | | # TODO: Handle nested parenthesis in the following regex. |
| 43 | | result = re.sub(r'\(([^)]+)\)', MatchChecker(args, kwargs), regex.pattern) |
| 44 | | return result.replace('^', '').replace('$', '') |
| | 49 | # Recursion is not necessary because the outermost matched parenthesis |
| | 50 | # will be replaced with the given argument. |
| | 51 | use_named_groups = bool(re_named_group.search(regex.pattern)) |
| | 52 | match_checker = MatchChecker(args, kwargs, use_named_groups) |
| | 53 | result = re_parenthesis.sub(match_checker, regex.pattern) |
| | 54 | # Strip unused regular expression syntax. |
| | 55 | result = re_unused.sub('', result) |
| | 56 | # Unescape special characters which could possibly be used in a URL. |
| | 57 | result = re_special.sub(r'\1', result) |
| | 58 | return result |
| 57 | | m = re.search(r'^\?P<(\w+)>(.*?)$', grouped) |
| 58 | | if m: # If this was a named group... |
| 59 | | # m.group(1) is the name of the group |
| 60 | | # m.group(2) is the regex. |
| 61 | | try: |
| 62 | | value = self.kwargs[m.group(1)] |
| 63 | | except KeyError: |
| 64 | | # It was a named group, but the arg was passed in as a |
| 65 | | # positional arg or not at all. |
| | 72 | |
| | 73 | # Handle regular expression extension notation. |
| | 74 | if grouped.startswith('?'): |
| | 75 | grouped = grouped[1:] |
| | 76 | if grouped.startswith(':'): |
| | 77 | # Parse the contents of this non-grouping parenthesis. |
| | 78 | value = re_parenthesis.sub(self, grouped[1:]) |
| | 79 | value = str(value) # TODO: Unicode? |
| | 80 | return handle_pipe(value) |
| | 81 | elif grouped.startswith('P'): |
| | 82 | # This is a named group. |
| | 83 | pass |
| | 84 | else: |
| | 85 | # Ignore the all other types of extension notation. |
| | 86 | return '' |
| | 87 | |
| | 88 | # If there is a named group in this regex, only parse named groups |
| | 89 | # ignoring non-named arguments. |
| | 90 | if self.use_named_groups: |
| | 91 | if m: # If this was a named group... |
| | 92 | # m.group(1) is the name of the group |
| | 93 | # m.group(2) is the regex. |
| 67 | | value = self.args[self.current_arg] |
| 68 | | self.current_arg += 1 |
| 69 | | except IndexError: |
| 70 | | # The arg wasn't passed in. |
| 71 | | raise NoReverseMatch('Not enough positional arguments passed in') |
| 72 | | test_regex = m.group(2) |
| 73 | | else: # Otherwise, this was a positional (unnamed) group. |
| | 95 | value = self.kwargs[m.group(1)] |
| | 96 | except KeyError: |
| | 97 | # It was a named group, but the arg was passed in as a |
| | 98 | # positional arg or not at all. |
| | 99 | try: |
| | 100 | value = self.args[self.current_arg] |
| | 101 | self.current_arg += 1 |
| | 102 | except IndexError: |
| | 103 | # The arg wasn't passed in. |
| | 104 | raise NoReverseMatch('Not enough positional arguments passed in') |
| | 105 | test_regex = m.group(2) |
| | 106 | else: |