Regex, чтобы поймать последний подшаблон

1

Я пытаюсь создать регулярное выражение, которое заменит токены% aa% и% cc% внутри строки. Все случаи перечислены ниже:

1) /%aa%/%cc%/bb   => should replace only %cc%
2) /%aa%/%cc%/ac   => should replace only %cc%
3) /bb/%aa%/%cc%   => should replace only the last %cc%
4) /bb/%aa%        => should replace %aa%
5) /bb/ac/%aa%/%cc%/ac/bb => should replace only the last %cc%

У меня есть следующее регулярное выражение, которое охватывает большую часть случая, ожидая 2 и 5, в основном те, которые содержат те же символы, что и токены.

Regex pattern: %(?|(?|aa)|(?|cc))%(?=[^(aa|cc)]*($)+)

Язык - это PHP.

Благодарю.

Теги:

1 ответ

0
Лучший ответ

В вашем регулярном выражении содержатся избыточные группы сброса ветвей ((?|...|...)) и коррумпированная группировка, которая помещается в класс символов [^(aa|cc)]*, и конец привязки строки количественно (($)+), что также является ошибкой пользователя (нет необходимости фиксировать якорь здесь, и достаточно проверить его один раз).

Вы можете использовать следующее регулярное выражение:

'~%(?:aa|cc)%(?!.*%(?:aa|cc)%)~'

См. Демо-версию regex

Для автономных строк вы также можете добавить модификатор ~s singleline (DOTALL): '~%(?:aa|cc)%(?!.*%(?:aa|cc)%)~s'.

Отрицательный lookahead (?!.*%(?:aa|cc)%) не соответствует совпадению, если либо aa либо cc появляются после найденного aa или cc.

  • 1
    Большое спасибо, @Wiktor Stribiżew. Это именно то, что мне было нужно. Последние два дня я боролся с этим, читая всех репетиторов, которые я мог найти. Спасибо за включение объяснения. :)
  • 0
    Еще один совет: здесь я использую группы без захвата (?:...) , они предназначены только для группировки, а не для захвата подтекстов. Это удобно, поскольку данные о совпадениях не переполняются ненужными подспариваниями.
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню