We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Incorrect parsing of complex urls in django
Sentry is parsing a complex URL as `/api/{version})/log` instead of `/api/{version}/log`.

<img width="207" alt="Screenshot 2020-10-17 at 10 40 47 AM" src="https://user-images.githubusercontent.com/4463796/96328987-70cb1c80-1066-11eb-94a4-ff8e15fb81ed.png">


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `sentry_sdk/integrations/django/transactions.py`
Content:
```
1 """
2 Copied from raven-python. Used for
3 `DjangoIntegration(transaction_fron="raven_legacy")`.
4 """
5 
6 from __future__ import absolute_import
7 
8 import re
9 
10 from sentry_sdk._types import MYPY
11 
12 if MYPY:
13     from django.urls.resolvers import URLResolver
14     from typing import Dict
15     from typing import List
16     from typing import Optional
17     from django.urls.resolvers import URLPattern
18     from typing import Tuple
19     from typing import Union
20     from re import Pattern
21 
22 try:
23     from django.urls import get_resolver
24 except ImportError:
25     from django.core.urlresolvers import get_resolver
26 
27 
28 def get_regex(resolver_or_pattern):
29     # type: (Union[URLPattern, URLResolver]) -> Pattern[str]
30     """Utility method for django's deprecated resolver.regex"""
31     try:
32         regex = resolver_or_pattern.regex
33     except AttributeError:
34         regex = resolver_or_pattern.pattern.regex
35     return regex
36 
37 
38 class RavenResolver(object):
39     _optional_group_matcher = re.compile(r"\(\?\:([^\)]+)\)")
40     _named_group_matcher = re.compile(r"\(\?P<(\w+)>[^\)]+\)")
41     _non_named_group_matcher = re.compile(r"\([^\)]+\)")
42     # [foo|bar|baz]
43     _either_option_matcher = re.compile(r"\[([^\]]+)\|([^\]]+)\]")
44     _camel_re = re.compile(r"([A-Z]+)([a-z])")
45 
46     _cache = {}  # type: Dict[URLPattern, str]
47 
48     def _simplify(self, pattern):
49         # type: (str) -> str
50         r"""
51         Clean up urlpattern regexes into something readable by humans:
52 
53         From:
54         > "^(?P<sport_slug>\w+)/athletes/(?P<athlete_slug>\w+)/$"
55 
56         To:
57         > "{sport_slug}/athletes/{athlete_slug}/"
58         """
59         # remove optional params
60         # TODO(dcramer): it'd be nice to change these into [%s] but it currently
61         # conflicts with the other rules because we're doing regexp matches
62         # rather than parsing tokens
63         result = self._optional_group_matcher.sub(lambda m: "%s" % m.group(1), pattern)
64 
65         # handle named groups first
66         result = self._named_group_matcher.sub(lambda m: "{%s}" % m.group(1), result)
67 
68         # handle non-named groups
69         result = self._non_named_group_matcher.sub("{var}", result)
70 
71         # handle optional params
72         result = self._either_option_matcher.sub(lambda m: m.group(1), result)
73 
74         # clean up any outstanding regex-y characters.
75         result = (
76             result.replace("^", "")
77             .replace("$", "")
78             .replace("?", "")
79             .replace("//", "/")
80             .replace("\\", "")
81         )
82 
83         return result
84 
85     def _resolve(self, resolver, path, parents=None):
86         # type: (URLResolver, str, Optional[List[URLResolver]]) -> Optional[str]
87 
88         match = get_regex(resolver).search(path)  # Django < 2.0
89 
90         if not match:
91             return None
92 
93         if parents is None:
94             parents = [resolver]
95         elif resolver not in parents:
96             parents = parents + [resolver]
97 
98         new_path = path[match.end() :]
99         for pattern in resolver.url_patterns:
100             # this is an include()
101             if not pattern.callback:
102                 match_ = self._resolve(pattern, new_path, parents)
103                 if match_:
104                     return match_
105                 continue
106             elif not get_regex(pattern).search(new_path):
107                 continue
108 
109             try:
110                 return self._cache[pattern]
111             except KeyError:
112                 pass
113 
114             prefix = "".join(self._simplify(get_regex(p).pattern) for p in parents)
115             result = prefix + self._simplify(get_regex(pattern).pattern)
116             if not result.startswith("/"):
117                 result = "/" + result
118             self._cache[pattern] = result
119             return result
120 
121         return None
122 
123     def resolve(
124         self,
125         path,  # type: str
126         urlconf=None,  # type: Union[None, Tuple[URLPattern, URLPattern, URLResolver], Tuple[URLPattern]]
127     ):
128         # type: (...) -> str
129         resolver = get_resolver(urlconf)
130         match = self._resolve(resolver, path)
131         return match or path
132 
133 
134 LEGACY_RESOLVER = RavenResolver()
135
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/sentry_sdk/integrations/django/transactions.py b/sentry_sdk/integrations/django/transactions.py
--- a/sentry_sdk/integrations/django/transactions.py
+++ b/sentry_sdk/integrations/django/transactions.py
@@ -37,7 +37,7 @@
 
 class RavenResolver(object):
     _optional_group_matcher = re.compile(r"\(\?\:([^\)]+)\)")
-    _named_group_matcher = re.compile(r"\(\?P<(\w+)>[^\)]+\)")
+    _named_group_matcher = re.compile(r"\(\?P<(\w+)>[^\)]+\)+")
     _non_named_group_matcher = re.compile(r"\([^\)]+\)")
     # [foo|bar|baz]
     _either_option_matcher = re.compile(r"\[([^\]]+)\|([^\]]+)\]")

{"golden_diff": "diff --git a/sentry_sdk/integrations/django/transactions.py b/sentry_sdk/integrations/django/transactions.py\n--- a/sentry_sdk/integrations/django/transactions.py\n+++ b/sentry_sdk/integrations/django/transactions.py\n@@ -37,7 +37,7 @@\n \n class RavenResolver(object):\n     _optional_group_matcher = re.compile(r\"\\(\\?\\:([^\\)]+)\\)\")\n-    _named_group_matcher = re.compile(r\"\\(\\?P<(\\w+)>[^\\)]+\\)\")\n+    _named_group_matcher = re.compile(r\"\\(\\?P<(\\w+)>[^\\)]+\\)+\")\n     _non_named_group_matcher = re.compile(r\"\\([^\\)]+\\)\")\n     # [foo|bar|baz]\n     _either_option_matcher = re.compile(r\"\\[([^\\]]+)\\|([^\\]]+)\\]\")\n", "issue": "Incorrect parsing of complex urls in django\nSentry is parsing a complex URL as `/api/{version})/log` instead of `/api/{version}/log`.\r\n\r\n<img width=\"207\" alt=\"Screenshot 2020-10-17 at 10 40 47 AM\" src=\"https://user-images.githubusercontent.com/4463796/96328987-70cb1c80-1066-11eb-94a4-ff8e15fb81ed.png\">\r\n\n", "before_files": [{"content": "\"\"\"\nCopied from raven-python. Used for\n`DjangoIntegration(transaction_fron=\"raven_legacy\")`.\n\"\"\"\n\nfrom __future__ import absolute_import\n\nimport re\n\nfrom sentry_sdk._types import MYPY\n\nif MYPY:\n    from django.urls.resolvers import URLResolver\n    from typing import Dict\n    from typing import List\n    from typing import Optional\n    from django.urls.resolvers import URLPattern\n    from typing import Tuple\n    from typing import Union\n    from re import Pattern\n\ntry:\n    from django.urls import get_resolver\nexcept ImportError:\n    from django.core.urlresolvers import get_resolver\n\n\ndef get_regex(resolver_or_pattern):\n    # type: (Union[URLPattern, URLResolver]) -> Pattern[str]\n    \"\"\"Utility method for django's deprecated resolver.regex\"\"\"\n    try:\n        regex = resolver_or_pattern.regex\n    except AttributeError:\n        regex = resolver_or_pattern.pattern.regex\n    return regex\n\n\nclass RavenResolver(object):\n    _optional_group_matcher = re.compile(r\"\\(\\?\\:([^\\)]+)\\)\")\n    _named_group_matcher = re.compile(r\"\\(\\?P<(\\w+)>[^\\)]+\\)\")\n    _non_named_group_matcher = re.compile(r\"\\([^\\)]+\\)\")\n    # [foo|bar|baz]\n    _either_option_matcher = re.compile(r\"\\[([^\\]]+)\\|([^\\]]+)\\]\")\n    _camel_re = re.compile(r\"([A-Z]+)([a-z])\")\n\n    _cache = {}  # type: Dict[URLPattern, str]\n\n    def _simplify(self, pattern):\n        # type: (str) -> str\n        r\"\"\"\n        Clean up urlpattern regexes into something readable by humans:\n\n        From:\n        > \"^(?P<sport_slug>\\w+)/athletes/(?P<athlete_slug>\\w+)/$\"\n\n        To:\n        > \"{sport_slug}/athletes/{athlete_slug}/\"\n        \"\"\"\n        # remove optional params\n        # TODO(dcramer): it'd be nice to change these into [%s] but it currently\n        # conflicts with the other rules because we're doing regexp matches\n        # rather than parsing tokens\n        result = self._optional_group_matcher.sub(lambda m: \"%s\" % m.group(1), pattern)\n\n        # handle named groups first\n        result = self._named_group_matcher.sub(lambda m: \"{%s}\" % m.group(1), result)\n\n        # handle non-named groups\n        result = self._non_named_group_matcher.sub(\"{var}\", result)\n\n        # handle optional params\n        result = self._either_option_matcher.sub(lambda m: m.group(1), result)\n\n        # clean up any outstanding regex-y characters.\n        result = (\n            result.replace(\"^\", \"\")\n            .replace(\"$\", \"\")\n            .replace(\"?\", \"\")\n            .replace(\"//\", \"/\")\n            .replace(\"\\\\\", \"\")\n        )\n\n        return result\n\n    def _resolve(self, resolver, path, parents=None):\n        # type: (URLResolver, str, Optional[List[URLResolver]]) -> Optional[str]\n\n        match = get_regex(resolver).search(path)  # Django < 2.0\n\n        if not match:\n            return None\n\n        if parents is None:\n            parents = [resolver]\n        elif resolver not in parents:\n            parents = parents + [resolver]\n\n        new_path = path[match.end() :]\n        for pattern in resolver.url_patterns:\n            # this is an include()\n            if not pattern.callback:\n                match_ = self._resolve(pattern, new_path, parents)\n                if match_:\n                    return match_\n                continue\n            elif not get_regex(pattern).search(new_path):\n                continue\n\n            try:\n                return self._cache[pattern]\n            except KeyError:\n                pass\n\n            prefix = \"\".join(self._simplify(get_regex(p).pattern) for p in parents)\n            result = prefix + self._simplify(get_regex(pattern).pattern)\n            if not result.startswith(\"/\"):\n                result = \"/\" + result\n            self._cache[pattern] = result\n            return result\n\n        return None\n\n    def resolve(\n        self,\n        path,  # type: str\n        urlconf=None,  # type: Union[None, Tuple[URLPattern, URLPattern, URLResolver], Tuple[URLPattern]]\n    ):\n        # type: (...) -> str\n        resolver = get_resolver(urlconf)\n        match = self._resolve(resolver, path)\n        return match or path\n\n\nLEGACY_RESOLVER = RavenResolver()\n", "path": "sentry_sdk/integrations/django/transactions.py"}], "after_files": [{"content": "\"\"\"\nCopied from raven-python. Used for\n`DjangoIntegration(transaction_fron=\"raven_legacy\")`.\n\"\"\"\n\nfrom __future__ import absolute_import\n\nimport re\n\nfrom sentry_sdk._types import MYPY\n\nif MYPY:\n    from django.urls.resolvers import URLResolver\n    from typing import Dict\n    from typing import List\n    from typing import Optional\n    from django.urls.resolvers import URLPattern\n    from typing import Tuple\n    from typing import Union\n    from re import Pattern\n\ntry:\n    from django.urls import get_resolver\nexcept ImportError:\n    from django.core.urlresolvers import get_resolver\n\n\ndef get_regex(resolver_or_pattern):\n    # type: (Union[URLPattern, URLResolver]) -> Pattern[str]\n    \"\"\"Utility method for django's deprecated resolver.regex\"\"\"\n    try:\n        regex = resolver_or_pattern.regex\n    except AttributeError:\n        regex = resolver_or_pattern.pattern.regex\n    return regex\n\n\nclass RavenResolver(object):\n    _optional_group_matcher = re.compile(r\"\\(\\?\\:([^\\)]+)\\)\")\n    _named_group_matcher = re.compile(r\"\\(\\?P<(\\w+)>[^\\)]+\\)+\")\n    _non_named_group_matcher = re.compile(r\"\\([^\\)]+\\)\")\n    # [foo|bar|baz]\n    _either_option_matcher = re.compile(r\"\\[([^\\]]+)\\|([^\\]]+)\\]\")\n    _camel_re = re.compile(r\"([A-Z]+)([a-z])\")\n\n    _cache = {}  # type: Dict[URLPattern, str]\n\n    def _simplify(self, pattern):\n        # type: (str) -> str\n        r\"\"\"\n        Clean up urlpattern regexes into something readable by humans:\n\n        From:\n        > \"^(?P<sport_slug>\\w+)/athletes/(?P<athlete_slug>\\w+)/$\"\n\n        To:\n        > \"{sport_slug}/athletes/{athlete_slug}/\"\n        \"\"\"\n        # remove optional params\n        # TODO(dcramer): it'd be nice to change these into [%s] but it currently\n        # conflicts with the other rules because we're doing regexp matches\n        # rather than parsing tokens\n        result = self._optional_group_matcher.sub(lambda m: \"%s\" % m.group(1), pattern)\n\n        # handle named groups first\n        result = self._named_group_matcher.sub(lambda m: \"{%s}\" % m.group(1), result)\n\n        # handle non-named groups\n        result = self._non_named_group_matcher.sub(\"{var}\", result)\n\n        # handle optional params\n        result = self._either_option_matcher.sub(lambda m: m.group(1), result)\n\n        # clean up any outstanding regex-y characters.\n        result = (\n            result.replace(\"^\", \"\")\n            .replace(\"$\", \"\")\n            .replace(\"?\", \"\")\n            .replace(\"//\", \"/\")\n            .replace(\"\\\\\", \"\")\n        )\n\n        return result\n\n    def _resolve(self, resolver, path, parents=None):\n        # type: (URLResolver, str, Optional[List[URLResolver]]) -> Optional[str]\n\n        match = get_regex(resolver).search(path)  # Django < 2.0\n\n        if not match:\n            return None\n\n        if parents is None:\n            parents = [resolver]\n        elif resolver not in parents:\n            parents = parents + [resolver]\n\n        new_path = path[match.end() :]\n        for pattern in resolver.url_patterns:\n            # this is an include()\n            if not pattern.callback:\n                match_ = self._resolve(pattern, new_path, parents)\n                if match_:\n                    return match_\n                continue\n            elif not get_regex(pattern).search(new_path):\n                continue\n\n            try:\n                return self._cache[pattern]\n            except KeyError:\n                pass\n\n            prefix = \"\".join(self._simplify(get_regex(p).pattern) for p in parents)\n            result = prefix + self._simplify(get_regex(pattern).pattern)\n            if not result.startswith(\"/\"):\n                result = \"/\" + result\n            self._cache[pattern] = result\n            return result\n\n        return None\n\n    def resolve(\n        self,\n        path,  # type: str\n        urlconf=None,  # type: Union[None, Tuple[URLPattern, URLPattern, URLResolver], Tuple[URLPattern]]\n    ):\n        # type: (...) -> str\n        resolver = get_resolver(urlconf)\n        match = self._resolve(resolver, path)\n        return match or path\n\n\nLEGACY_RESOLVER = RavenResolver()\n", "path": "sentry_sdk/integrations/django/transactions.py"}]}