Recursive BBCode Parsing

北慕城南 提交于 2019-11-28 09:56:18

问题


I'm trying to parse BBCode in my script. Now, it works seamelessly, until I try to indent BBCode that's more than just bold or underline - such as spoiler, url, font size, etc. - then it screws up. Here's my code:

function parse_bbcode($text) {
    global $db;
    $oldtext = $text;
    $bbcodes = $db->select('*', 'bbcodes');
    foreach ($bbcodes as $bbcode) {
        switch ($bbcode->type) {
            case 'simple': {
                $find = '{content}';
                $replace = '${1}';
                $text = preg_replace(
                    '/\['.$bbcode->tag.'\](.+)\[\/'.$bbcode->tag.'\]/i',
                    str_replace($find, $replace, $bbcode->html),
                    $text);
                    break;
            }
            case 'property':
            case 'options': {
                $find = array ( '{property}', '{content}' );
                $replace = array ( '${1}', '${2}' );
                $text = preg_replace(
                    '/\['.$bbcode->tag.'\=(.[^\"]*)\](.+)\[\/'.$bbcode->tag.'\]/i',
                    str_replace($find, $replace, $bbcode->html),
                    $text);
                    break;
            }
        }
    }
    return $text;
}

Now my guess is that the RegEx doesn't like the recursiveness in the pattern. How can I improve it? A sample $bbcode object is as such:

stdClass::__set_state(array(
   'id' => '2',
   'name' => 'Italic',
   'type' => 'simple',
   'tag' => 'i',
   'button_image' => NULL,
   'button_text' => '<i>I</i>',
   'options' => '',
   'prompt' => NULL,
   'html' => '<i>{content}</i>',
   'order' => '1',
))
stdClass::__set_state(array(
   'id' => '3',
   'name' => 'URL',
   'type' => 'property',
   'tag' => 'url',
   'button_image' => NULL,
   'button_text' => 'http://',
   'options' => '',
   'prompt' => 'URL address',
   'html' => '<a href="{property}">{content}</a>',
   'order' => '4',
))

回答1:


As gordon said in comments PHP has a BBCode parser, so no reason to reinvent the wheel.

The native parser is a PECL package though, so you will have to install it. If that's not an option (for instance due to shared hosting), there is also a PEAR package: http://pear.php.net/package/HTML_BBCodeParser

In addition to those, you can take a look at forums using BB code source code, and either use their parser, or improve it. There is also several PHP implementations listed at http://www.bbcode.org/implementations.php




回答2:


Correctly parsing BBcode using regex is non-trival. The codes may be nested. CODE tags may contain BBCodes which must be ignored by the parser. Certain tags may not appear inside of other tags. etc. However, it can be done. I recently overhauled the BBCode parser for the FluxBB open source forum software. You may want to check it out in action:

New 2011 FluxBB Parser

Note that this new parser has not yet been incorporated into the FluxBB codebase.



来源:https://stackoverflow.com/questions/6773192/recursive-bbcode-parsing

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!