Используя ваш оригинальный пример, вы можете использовать рекурсивное выражение:
"%(/\w+)(?>[^(/\w+)]?|(?R))%"
Это работает мои подходящие (/ \ w +) подвыражения в свою очередь. Перед матчем за
"/a/b/1/2/3/4"
Будет:
Array
(
[0] => Array
(
[0] => /a [1] => /b [2] => /1 [3] => /2 [4] => /3 [5] => /4
)
...
Однако ваши последующие примеры усложняют ситуацию. Простое совпадение 0 или более вернет только последнее (жадное) или первое (не жадное) совпадение - не все подспаривания. preg_match_all не сможет обработать ваше динамическое выражение.
Вам нужно будет уточнить, чего вы хотите добиться, более подробно, прежде чем будет найдено подходящее решение.