diff --git a/django/contrib/admindocs/utils.py b/django/contrib/admindocs/utils.py index 8cb789016f..b3a0526874 100644 --- a/django/contrib/admindocs/utils.py +++ b/django/contrib/admindocs/utils.py @@ -142,6 +142,11 @@ named_group_matcher = _lazy_re_compile(r'\(\?P(<\w+>)') unnamed_group_matcher = _lazy_re_compile(r'\(') +def replace_metacharacters(pattern): + """Remove unescaped metacharacters from the pattern.""" + return pattern.replace('^', '').replace('$', '').replace('?', '') + + def replace_named_groups(pattern): r""" Find named groups in `pattern` and replace them with the group name. E.g., diff --git a/django/contrib/admindocs/views.py b/django/contrib/admindocs/views.py index ab6e75c811..ffe4e13fa4 100644 --- a/django/contrib/admindocs/views.py +++ b/django/contrib/admindocs/views.py @@ -8,7 +8,7 @@ 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_named_groups, replace_unnamed_groups, + replace_metacharacters, replace_named_groups, replace_unnamed_groups, ) from django.core.exceptions import ImproperlyConfigured, ViewDoesNotExist from django.db import models @@ -412,8 +412,7 @@ def simplify_regex(pattern): """ pattern = replace_named_groups(pattern) pattern = replace_unnamed_groups(pattern) - # clean up any outstanding regex-y characters. - pattern = pattern.replace('^', '').replace('$', '').replace('?', '') + pattern = replace_metacharacters(pattern) if not pattern.startswith('/'): pattern = '/' + pattern return pattern