Fixed #28135 -- Made simplify_regex() handle non-capturing groups.
This commit is contained in:
parent
fdfa97fb16
commit
0a17666045
|
@ -137,9 +137,10 @@ if docutils_is_available:
|
|||
for name, urlbase in ROLES.items():
|
||||
create_reference_role(name, urlbase)
|
||||
|
||||
# Match the beginning of a named or unnamed group.
|
||||
# Match the beginning of a named, unnamed, or non-capturing groups.
|
||||
named_group_matcher = _lazy_re_compile(r'\(\?P(<\w+>)')
|
||||
unnamed_group_matcher = _lazy_re_compile(r'\(')
|
||||
non_capturing_group_matcher = _lazy_re_compile(r'\(\?\:')
|
||||
|
||||
|
||||
def replace_metacharacters(pattern):
|
||||
|
@ -210,3 +211,18 @@ def replace_unnamed_groups(pattern):
|
|||
final_pattern += pattern[:start] + '<var>'
|
||||
prev_end = end
|
||||
return final_pattern + pattern[prev_end:]
|
||||
|
||||
|
||||
def remove_non_capturing_groups(pattern):
|
||||
r"""
|
||||
Find non-capturing groups in the given `pattern` and remove them, e.g.
|
||||
1. (?P<a>\w+)/b/(?:\w+)c(?:\w+) => (?P<a>\\w+)/b/c
|
||||
2. ^(?:\w+(?:\w+))a => ^a
|
||||
3. ^a(?:\w+)/b(?:\w+) => ^a/b
|
||||
"""
|
||||
group_start_end_indices = _find_groups(pattern, non_capturing_group_matcher)
|
||||
final_pattern, prev_end = '', None
|
||||
for start, end, _ in group_start_end_indices:
|
||||
final_pattern += pattern[prev_end:start]
|
||||
prev_end = end
|
||||
return final_pattern + pattern[prev_end:]
|
||||
|
|
|
@ -8,7 +8,8 @@ from django.contrib import admin
|
|||
from django.contrib.admin.views.decorators import staff_member_required
|
||||
from django.contrib.admindocs import utils
|
||||
from django.contrib.admindocs.utils import (
|
||||
replace_metacharacters, replace_named_groups, replace_unnamed_groups,
|
||||
remove_non_capturing_groups, replace_metacharacters, replace_named_groups,
|
||||
replace_unnamed_groups,
|
||||
)
|
||||
from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist
|
||||
from django.db import models
|
||||
|
@ -410,6 +411,7 @@ def simplify_regex(pattern):
|
|||
example, turn "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
|
||||
into "/<sport_slug>/athletes/<athlete_slug>/".
|
||||
"""
|
||||
pattern = remove_non_capturing_groups(pattern)
|
||||
pattern = replace_named_groups(pattern)
|
||||
pattern = replace_unnamed_groups(pattern)
|
||||
pattern = replace_metacharacters(pattern)
|
||||
|
|
|
@ -397,6 +397,13 @@ class AdminDocViewFunctionsTests(SimpleTestCase):
|
|||
(r'^(?P<a>(x|y))/b/(?P<c>\w+)', '/<a>/b/<c>'),
|
||||
(r'^(?P<a>(x|y))/b/(?P<c>\w+)ab', '/<a>/b/<c>ab'),
|
||||
(r'^(?P<a>(x|y)(\(|\)))/b/(?P<c>\w+)ab', '/<a>/b/<c>ab'),
|
||||
# Non-capturing groups.
|
||||
(r'^a(?:\w+)b', '/ab'),
|
||||
(r'^a(?:(x|y))', '/a'),
|
||||
(r'^(?:\w+(?:\w+))a', '/a'),
|
||||
(r'^a(?:\w+)/b(?:\w+)', '/a/b'),
|
||||
(r'(?P<a>\w+)/b/(?:\w+)c(?:\w+)', '/<a>/b/c'),
|
||||
(r'(?P<a>\w+)/b/(\w+)/(?:\w+)c(?:\w+)', '/<a>/b/<var>/c'),
|
||||
# Single and repeated metacharacters.
|
||||
(r'^a', '/a'),
|
||||
(r'^^a', '/a'),
|
||||
|
|
Loading…
Reference in New Issue