Начать регулярное выражение с последнего вхождения тега

Я пытаюсь идентифицировать bbcodes внутри текстов, используя REGEX.

У меня есть следующий текст:

Lorem ipsum dolor sit amet, [color] consectetur adipisicing el it labore et [color=red]dolore magna aliqua[/color] minim veniam.

И в настоящее время я использую этот шаблон:

/\[([a-z0-9]+).+?\[\/\1\]/i

Но ловит это:

[color] consectetur adipisicing el it labore et [color=red]dolore magna aliqua[/color]

вместо этого:

[color=red]dolore magna aliqua[/color]

Я думаю о двух решениях, но я не знаю, как заставить его работать:

  1. Не разрешать теги внутри содержимого тегов. Затем [b]this [b] won't be allowed[/b];
  2. Запуск шаблона с последнего вхождения тега.

Спасибо за помощь,

JG


person Junior Grossi    schedule 30.05.2017    source источник


Ответы (1)


Ваше регулярное выражение находит самое левое вхождение [, за которым следует BBtag, а затем .+? соответствует любым 1+ символам, кроме разрыва строки, как можно меньшему количеству, но столько, сколько необходимо, чтобы найти самый левый [/<CLOSE_TAG>].

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

\[([a-z0-9]+)[^\[]*(?:\[(?!\1\b)[^\[]*)*?\[\/\1\]

См. демонстрацию регулярного выражения.

Это почти то же самое, что и \[([a-z0-9]+)(?:(?!\[\1\b).)+?\[\/\1\], который может быть немного более читабельным, но менее эффективным.

Подробности:

  • \[ - открытая скобка
  • ([a-z0-9]+) - Группа 1 (имя тега): 1+ буквенно-цифровых символов
  • [^\[]* - ноль или более символов, кроме [
  • (?:\[(?!\1\b)[^\[]*)*? - 0+ sequences (as few as possible) matching
    • \[(?!\1\b) - a [ not followed with Group 1 text as a whole word
    • [^\[]* - ноль или более символов, кроме [
  • \[ - a [
  • \/ - a /
  • \1 - Текст группы 1
  • \] - a ].
person Wiktor Stribiżew    schedule 30.05.2017
comment
ВОТ ЭТО ДА! Большое спасибо! Это сработало отлично! Я пытался найти случай, когда он не работает, но никого не нашел :-) Круто! Спасибо! - person Junior Grossi; 30.05.2017