Лучший способ разбора bbcode

Я хотел бы работать над фильтром bbcode для веб-сайта php. (Я использую cakephp, это будет помощник bbcode) У меня есть некоторые требования.

Bbcodes могут быть вложенными. Так что что-то вроде этого действительно.

[block]  
    [block]  
    [/block]  
    [block]  
        [block]  
        [/block]  
    [/block]  
[/block]  

Bbcodes может иметь 0 или более параметров.

Exemple:

[video: url="url", width="500", height="500"]Title[/video]

Bbcodes может иметь поведение mutliple.

скажем, [url]text[/url] будет преобразовано в [url:url="text"]text[/url] или видео bbcode будет иметь возможность выбирать между youtube, dailymotion....

Я думаю, что это покрывает большую часть моих потребностей. Я уже сделал кое-что с regex. Но моей самой большой проблемой было соответствие параметров. Фактически, я получил вложенный bbcode для работы и bbcode с 0 параметрами. Но когда я добавил регулярное выражение для параметров, оно не соответствовало вложенному bbcode правильно.

"[($tag)(=.*)"](.*)[/]" // это не так .* но не-жирный matcher

у меня нет полного выражения со мной прямо сейчас, но у меня было что-то, что выглядело так(выше).

Итак, есть способ эффективно сопоставить bbcode с regex или чем-то еще. Единственное, что я могу придумать, это использовать шаблон посетителя и разделить мой текст с каждым возможным тегом таким образом, у меня может быть немного больше контроля над моим разбором текста, и я мог бы, вероятно, проверить свой документ, так что если входной текст не имеет действительного bbcode. Я мог бы уведомить Пользователя об ошибке перед сохранением что угодно.

Я бы использовал sablecc для создания моего текстового анализатора. http://sablecc.org/

идея получше? или что-нибудь, что может привести к эффективному гибкому парсеру bbcode?

спасибо и извините за мой плохой английский...

5 ответов


вот как по PECL и груша библиотека синтаксического анализа BBCode. Программное обеспечение достаточно сложно, не изобретая годы работы самостоятельно.

Если ни один из них не является вариантом, я бы сосредоточился на превращении BBCode в допустимую строку XML, а затем использовал вашу любимую процедуру синтаксического анализа XML. Очень грубая идея, но

  1. запустите код через htmlspecialchars, чтобы избежать любых объектов, которые нуждаются побег

  2. преобразуйте все символы [ и ] в соответственно

  3. Не забудьте учитывать двоеточие в таких случаях, как [tagname:

Если BBCode был вложен правильно, вы должны быть настроены на передачу этой строки в объект синтаксического анализа XML (SimpleXML, DOMDocument и т. д.)


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

вот пара, я уверен, что есть еще, если вы посмотрите вокруг:
PECL bbcode
груша HTML_BBCodeParser


Я сам изучал Парсеры bbcode. Большинство из них используют regex и PHP4 и производят ошибки на PHP 5.2+ или вообще не работают. PECL bbcode и PEAR HTML_BBCodeParser, похоже, больше не поддерживаются (в конце 2012 года) и не легко устанавливаются на общую настройку хостинга, с которой я должен работать. StringParser_BBCode работает с некоторыми незначительными настройками для 5.2+, но метод добавления новых тегов неуклюжий, и он был последний раз обновлен в 2008 году.

похоронен на 4-й странице из поиска Bing (я был в отчаянии) я нашел jBBCode, который появляется новый и требует PHP 5.3. MIT Lisence. Я еще не пробовал создавать пользовательские теги, но пока это единственный, который я пробовал, который работает из коробки на общей учетной записи хостинга с PHP 5.3.


отвечая на: "есть идея получше?"(и я предполагаю, что это было приглашение не только для улучшения конкретных предложений bbcode)

недавно мы посмотрели на маршрут bbcode и решили использовать htmlpurifier. Это решение частично основывалось на (предположительно предвзятом) сравнении различных методов, перечисленных группой htmlpurifier здесь и обсуждение bbcode (опять же, htmlpurifer group)здесь


использовать preg_split() с PREG_DELIM_CAPTURE флаг для разделения исходного кода на теги и не-теги. Затем перебирайте теги, сохраняя стек открытых блоков (т. е. когда вы видите открывающий тег, добавьте его в массив. Когда вы видите закрывающий тег, удалите элементы из конца массива, пока закрывающий тег не совпадет с открывающим тегом.)