У меня есть регулярное выражение, которое захватывает теги BBcode. Работает отлично, за исключением небольшого глюка.
Вот текущее выражение:
\[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](.+)\[/\1\]
Вот некоторый текст, с которым он успешно сопоставляется, и группы, которые он создает:
[url=http://www.google.com]Перейти в Google![/url]< br> 1: URL
2: http://www.google.com
3: Иди в гугл![img]http://www.somesite.com/someimage.jpg[/img]
1: img
2: NULL
3: http://www.somesite.com/someimage.jpg[quote][quote]первая вложенная кавычка[/quote][quote]вторая вложенная кавычка[/quote][/quote]
1: кавычка
2: NULL
3: [quote]первая вложенная кавычка [/quote][quote]вторая вложенная цитата[/quote]
Все это здорово. Я могу обрабатывать вложенные теги, запуская третью группу совпадений с тем же регулярным выражением и рекурсивно обрабатывать все вложенные теги. Проблема в примере с использованием тегов [quote]. Обратите внимание, что третья группа совпадений представляет собой набор из двух тегов кавычек, поэтому мы ожидаем два совпадения. Однако мы получаем одно совпадение, например:
[quote]первая вложенная кавычка[/quote][quote]вторая вложенная кавычка[/quote]
1: кавычка
2: NULL
3: первая вложенная кавычка[/quote][quote]вторая вложенная кавычка
Аааа! Это совсем не то, чего мы хотели. Есть довольно простой способ исправить это, я изменяю регулярное выражение следующим образом:
\[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](.+)\[/\1\]
К этому:
\[([^=\[\]]+)[=\x22']*([^ \[\]]*)['\x22]*\](((?!\[/\1\]).)+)\[/\1\]
Добавляя ((?!\[/\1\]).)
, мы аннулируем все совпадение, если 3-я группа совпадений содержит закрывающий тег BBcode. Итак, теперь это работает, мы получаем два совпадения:
[quote]первая вложенная цитата[/quote][quote]вторая вложенная цитата[/quote]
[quote]первая вложенная цитата[/quote]
1: цитата
2: NULL
3: первая вложенная цитата[quote]вторая вложенная кавычка[/quote]
1: цитата
2: NULL 3: вторая вложенная кавычка
Я был счастлив, что исправил это, но теперь у нас другая проблема. Это новое регулярное выражение терпит неудачу в первом, где мы вкладываем два тега цитаты в один тег цитаты большего размера. Получаем два совпадения вместо одного:
[quote][quote]первая вложенная цитата[/quote][quote]вторая вложенная цитата[/quote][/quote]
[quote][quote]первая вложенная кавычка[/quote]
1: кавычка
2: NULL
3: [quote]первая вложенная кавычка[quote]вторая вложенная кавычка[/quote]
1: кавычка
2: NULL
3: вторая вложенная кавычка
Первое совпадение неверно, а второе совпадение, хотя и правильно сформированное, не является желаемым совпадением. Нам нужно было одно большое совпадение с третьей группой совпадений, состоящей из двух вложенных тегов кавычек, например, когда мы использовали первое выражение.
Какие-либо предложения? Если я смогу преодолеть этот пробел, у меня должно получиться довольно мощное выражение BBcode.