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