Лучший способ разобрать 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]
B-коды могут иметь многократное поведение.
Скажи [url]text[/url]
будет преобразован в [url:url="text"]text[/url]
или видео bbcode сможет выбирать между YouTube, Dailymotion....
Я думаю, что это покрывает большинство моих потребностей. Я уже что-то сделал с регулярным выражением. Но моей самой большой проблемой было сопоставление параметров. Фактически, я получил вложенный bbcode для работы и bbcode с 0 параметрами. Но когда я добавил регулярное выражение для параметров, оно не соответствовало вложенному bbcode правильно.
"\[($tag)(=.*)\"\](.*)\[\/\1\]"
// Это не было.* Но не готовый матч
У меня сейчас нет полного регулярного выражения, но у меня было нечто, похожее на это (см. Выше).
Так есть ли способ эффективно сопоставить bbcode с регулярным выражением или чем-то еще. Единственное, о чем я могу думать, - это использовать шаблон посетителя и разделять текст по каждому возможному тегу таким образом, я могу иметь немного больше контроля над моим синтаксическим анализом и, возможно, могу проверить свой документ, поэтому, если вводимый текст не не имеет действительного bbcode. Я мог бы уведомить пользователя с ошибкой перед сохранением чего-либо.
Я бы использовал sablecc для создания моего текстового парсера. http://sablecc.org/
Есть идея получше? или что-нибудь, что может привести к эффективному гибкому парсеру bbcode?
Спасибо и извините за мой плохой английский...
5 ответов
Есть и библиотека разбора pecl и PEAR BBCode. Программное обеспечение достаточно сложное, не изобретая годы работы самостоятельно.
Если ни один из этих вариантов не подходит, я бы сконцентрировался на том, чтобы превратить BBCode в правильную строку XML, а затем использовать вашу любимую процедуру синтаксического анализа XML. Очень очень грубая идея здесь, но
Запустите код через htmlspecialchars, чтобы избежать любых сущностей, которые нужно экранировать
Преобразуйте все символы [и] в <и> соответственно
Не забудьте учесть двоеточие в таких случаях, как [tagname:
Если BBCode был правильно вложен, вы должны быть готовы передать эту строку в объект синтаксического анализа XML (SimpleXML, DOMDocument и т. Д.)
Сам изучал парсеры 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, может быть проще разобраться в них, чем пытаться свернуть свою собственную:
Вот пара, я уверен, что есть еще, если вы посмотрите вокруг:
PECL bbcode
PEAR HTML_BBCodeParser
Отвечая на: "Есть идея получше?" (и я предполагаю, что это было приглашение не только для улучшения по сравнению с предложениями, специфичными для bbcode)
Недавно мы рассмотрели маршрут bbcode и решили использовать вместо него http://htmlpurifier.org/. Это решение было частично основано на (предположительно предвзятом, вероятно) сравнении между различными методами, перечисленными здесь группой htmlpurifier, и обсуждением bbcode (опять же, группой htmlpurifer) здесь
И для справки, я думаю, что ваш английский был очень хорош. Я уверен, что это намного лучше, чем я мог бы сделать на вашем родном языке.
Использование preg_split()
с PREG_DELIM_CAPTURE
флаг для разделения исходного кода на теги и не теги. Затем выполните итерации по тегам, сохраняя стек открытых блоков (т. Е. Когда вы видите открывающий тег, добавьте его в массив. Когда вы видите закрывающий тег, удаляйте элементы из конца массива, пока закрывающий тег не совпадет с открывающим тегом.)