Я продолжаю сталкиваться с ситуациями, когда мне нужно захватить несколько токенов из строки, и после бесчисленных попыток я не смог найти способ упростить процесс.
Итак, скажем, текст:
старт: тест тест-Lorem Ipsum-, сэр doloret-и т.д.-и т.д.-что-то: конец
В этом примере есть 8 элементов внутри, но говорят, что оно может иметь от 3 до 10 элементов.
Мне идеально понравилось бы что-то вроде этого: start:(?:(\w+)-?){3,10}:end
приятный и чистый, но он только фиксирует последнее совпадение. см. здесь
Обычно я использую что-то подобное в простых ситуациях:
start:(\w+)-(\w+)-(\w+)-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?-?(\w+)?:end
3 группы обязательны, а еще 7 необязательны из-за предела 10, но это не выглядит "приятным", и было бы больно писать и отслеживать, если максимальный предел составлял 100, а совпадения были более сложными. демо
И самое лучшее, что я мог сделать до сих пор:
start:(\w+)-((?1))-((?1))-?((?1))?-?((?1))?-?((?1))?-?((?1))?-?((?1))?:end
короче, особенно если матчи сложны, но все еще долго. демо
Кому-то удалось заставить его работать как однорежимное решение без программирования?
Мне больше всего интересно, как это можно сделать в PCRE, но другие вкусы тоже будут в порядке.
Обновление:
Цель состоит в том, чтобы проверить соответствие и зафиксировать отдельные токены внутри match 0
только с помощью RegEx без ограничения OS/Software/Programming-Language
Обновление 2 (щедрость):
С помощью @nhahtdh help я добрался до RegExp ниже, используя \G
:
(?:start:(?=(?:[\w]+(?:-|(?=:end))){3,10}:end)|(?!^)\G-)([\w]+)
demo еще короче, но может быть описана без повторения кода
Меня также интересует аромат ECMA, и поскольку он не поддерживает \G
, задается вопросом, есть ли другой способ, особенно без использования модификатора /g
.