Проблема в том, что \w
соответствует буквам, цифрам или _
. Он количественно определяется с помощью +
, жадного квантификатора, и, следовательно, делает необязательным следующий соседний шаблон, совпадающий с пустой строкой перед несоответствующим текстом. (\w+)_?([0-9]+)\/
будет захватывать все буквы, цифры, _
до /
в d_9000/
, и только последняя 0
попадет в Группу 3, поскольку [0-9]+
должен соответствовать хотя бы 1 цифре.
Вы можете исключить _
из \w
, используя [^\W_]
, и сделать шаблон _([0-9]+)
необязательным, обернув его необязательной группой без захвата:
\/a\/b\/c\/([^\W_]+)(?:_([0-9]+))?\/p1=(.*)\/p2=(.*)\/p3=(.*)\/(.*)
^^^^^^^ ^^^ ^^
См. это демо регулярных выражений .
Или, сделайте \w
ленивым, а не вычитайте _
из \w
(если может быть _
, отличное от того, что перед цифрами, которые вам нужно захватить):
\/a\/b\/c\/(\w*?)(?:_([0-9]+))?\/p1=(.*)\/p2=(.*)\/p3=(.*)\/(.*)
^^^^
См. еще одну демонстрацию регулярных выражений .
![enter image description here](https://i.stack.imgur.com/o3gq6.png)