I have a regexp:

```
import re

regexp = re.compile(r'^(?P<parts>(?:[\w-]+/?)+)/$')

```

It matches a string like `foo/bar/baz/` and put the `foo/bar/baz` in a group named `parts` (the `/?` combined with the `/$` support this).

This works perfectly fine, **until you match a string that doesn't end in a slash**. Then, it gets slower at a seemingly-exponential rate with each new char you add to the string you're matching.

### Example

```
# This is instant (trailing slash)
regexp.match('this-will-take-no-time-at-all/')

# This is slow
regexp.match('this-takes-about-5-seconds')

# This will not finish
regexp.match('this-probably-will-not-finish-until-the-day-star-turns-black')

```

I'm trying to understand why this specific recursion issue only happens when the `/$` (trailing slash) isn't in the string (i.e., a non-match). Could you help me understand the control flow of the underlying algorithm in both the trailing slash and the non trailing slash cases?

### Note

I'm not looking for a solution for my desired pattern. I'm trying to understand the specific regexp.
['https://Stackoverflow.com/questions/36248147', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/128463/']
It is getting slow due to [catastrophic backtracking](http://www.regular-expressions.info/catastrophic.html) in your regex:

You can fix catastrophic backtracking by using this regex:

```
^(?P<parts>(?:[\w-]+/)*[\w-]+)/$

```

As per the link above:

> 
> The **solution to avoid *catastrophic backtracking*** is simple. When nesting repetition operators, make absolutely sure that there is only one way to match the same match.
> 
> 
>
Wiktor Stribizew is correct. The issue is the question mark after the slash inside the repeating pattern. So, the pattern you gave:

```
'^(?P<parts>(?:[\w-]+/?)+)/$'

```

Says, look for one or more groups of one or more word characters or dashes possibly followed by a slash, then there should be a slash at the very end.

So, for a string like `arm/`, the inner grouping could be any of:

```
(arm)/
(ar)(m)/
(a)(rm)/
(a)(r)(m)/

```

As the string gets longer, if the regex fails to match on its first try, it will check more and more combinations to try to match. To avoid this the same match could be achieved with:

```
'^(?P<parts>(?:[\w-]+/)*[\w-]+)/$'

```

because this version can only match your target strings one way.