Лучший способ разобрать bbcode - PullRequest
9 голосов
/ 28 января 2009

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

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

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

Bb-коды могут иметь 0 или более параметров.

Пример:

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

Bb-коды могут иметь многократное поведение.

Допустим, [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 ]

8 голосов
/ 18 октября 2012

Сам изучал парсеры 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.

8 голосов
/ 28 января 2009

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

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

6 голосов
/ 29 января 2009

Имеется библиотека синтаксического анализа BBCode pecl и PEAR . Программное обеспечение достаточно сложное, не изобретая годы работы самостоятельно.

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

  1. Запустите код через htmlspecialchars, чтобы избежать любых сущностей, которым требуется экранирование

  2. Преобразовать все символы [и] в <и> соответственно

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

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

3 голосов
/ 28 января 2009

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

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

И для протокола, я думаю, что ваш английский был очень хорош. Я уверен, что это намного лучше, чем я мог бы сделать на вашем родном языке.

2 голосов
/ 09 марта 2010

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

...