开发者

How to use preg_replace() to apply hilight_string() to content between BBCode-like tags?

I'm trying to run 开发者_开发问答the preg_replace() function to replace the content in between two custom tags (i.e. [xcode]) within the string / content of the page.

What I want to do with the content between these custom tags is to run it through highlight_string() function and to remove those custom tags from the output.

Any idea how to do it?


So you want sort of a BBCode parser. The example below replaces [xcode] tags with whatever markup you like.

<?php
function highlight($text) {
    $text = preg_replace('#\[xcode\](.+?)\[\/xcode\]#msi', '<em>\1</em>', $text);
    return $text;
}
$text = '[xcode]Lorem ipsum[/xcode] dolor sit [xcode]amet[/xcode].';
echo highlight($text);
?>

Use preg_replace_callback() if you want to pass the matched text to a function:

<?php
function parse($text) {
    $text = preg_replace_callback('#\[xcode\](.+?)\[\/xcode\]#msi',
        function($matches) {
            return highlight_string($matches[1], 1);
        }
    , $text);
    return $text;
}
$text = '[xcode]Lorem ipsum[/xcode] dolor sit [xcode]amet[/xcode].';
echo bbcode($text);
?>

I'll include the source code of a BBCode parser that I made a long time ago. Feel free to use it.

<?php
function bbcode_lists($text) {
    $pattern = "#\[list(\=(1|a))?\](.*?)\[\/list\]#msi";
    while (preg_match($pattern, $text, $matches)) {
        $points = explode("[*]", $matches[3]);
        array_shift($points);
        for ($i = 0; $i < count($points); $i++) {
            $nls = split("[\n]", $points[$i]);
            $brs = count($nls) - 2;
            $points[$i] = preg_replace("[\r\n]", "<br />", $points[$i], $brs);
        }
        $replace = ($matches[2] != '1') ? ($matches[2] != 'a') ? '<ul>' : '<ol style="list-style:lower-alpha">' : '<ol style="list-style:decimal">';
        $replace .= "<li>";
        $replace .= implode("</li><li>", $points);
        $replace .= "</li>";
        $replace .= ($matches[2] == '1' || $matches[2] == 'a' ) ? '</ol>' : '</ul>';
        $text = preg_replace($pattern, $replace, $text, 1);
        $text = preg_replace("[\r\n]", "", $text);
    }
    return $text;
}
function bbcode_parse($text) {
    $text = preg_replace("[\r\n]", "<br />", $text);
    $smilies = Array(
        ':)' => 'smile.gif',
        ':d' => 'tongue2.gif',
        ':P' => 'tongue.gif',
        ':lol:' => 'lol.gif',
        ':D' => 'biggrin.gif',
        ';)' => 'wink.gif',
        ':zzz:' => 'zzz.gif',
        ':confused:' => 'confused.gif'
    );
    foreach ($smilies as $key => $value) {
        $text = str_replace($key, '<img src="/images/smilies/' . $value . '" alt="' . $key . '" />', $text);
    }
    if (!(!strpos($text, "[") && !strpos($text, "]"))) {
        $bbcodes = Array(
            '#\[b\](.*?)\[/b\]#si' => '<strong>$1</strong>',
            '#\[i\](.*?)\[/i\]#si' => '<em>$1</em>',
            '#\[u\](.*?)\[/u\]#si' => '<span class="u">$1</span>',
            '#\[s\](.*?)\[/s\]#si' => '<span class="s">$1</span>',
            '#\[size=(.*?)\](.*?)\[/size\]#si' => '<span style="font-size:$1">$2</span>',
            '#\[color=(.*?)\](.*?)\[/color\]#si' => '<span style="color:$1">$2</span>',
            '#\[url=(.*?)\](.*?)\[/url\]#si' => '<a href="$1" target="_blank">$2</a>',
            '#\[url\](.*?)\[/url\]#si' => '<a href="$1" target="_blank">$1</a>',
            '#\[img\](.*?)\[/img\]#si' => '<img src="$1" alt="" />',
            '#\[code\](.*?)\[/code\]#si' => '<div class="code">$1</div>'
        );
        $text = preg_replace(array_keys($bbcodes), $bbcodes, $text);

        $text = bbcode_lists($text);

        $quote_code = Array("'\[quote=(.*?)\](.*?)'i", "'\[quote](.*?)'i", "'\[/quote\]'i");
        $quote_html = Array('<blockquote><p class="quotetitle">Quote \1:</p>\2', '<blockquote>\2', '</blockquote>');
        $text = preg_replace($quote_code, $quote_html, $text);

    }
    return $text;
}
?>


basically,

 preg_replace_callback('~\[tag\](.+?)\[/tag\]~', function($matches) { whatever }, $text);

this doesn't handle nested tags though

complete example

$text = "hello [xcode] <? echo bar ?> [/xcode] world";

echo preg_replace_callback(
    '~\[xcode\](.+?)\[/xcode\]~', 
    function($matches) { 
        return highlight_string($matches[1], 1);
    }, 
    $text
);


<?php
$string = 'The quick brown fox jumped over the lazy dog.';
$patterns = array();
$patterns[0] = '/quick/';
$patterns[1] = '/brown/';
$patterns[2] = '/fox/';
$replacements = array();
$replacements[2] = 'bear';
$replacements[1] = 'black';
$replacements[0] = 'slow';
echo preg_replace($patterns, $replacements, $string);
?>

The above example will output:

The bear black slow jumped over the lazy dog.

http://php.net/manual/en/function.preg-replace.php

OR

str_replace should help you

http://php.net/manual/en/function.str-replace.php


Thanks to user187291's suggestion and preg_replace_callback specification I've ended up with the following outcome which does the job spot on! :

function parseTagsRecursive($input)
{

    $regex = '~\[xcode\](.+?)\[/xcode\]~';

    if (is_array($input)) {
        $input = highlight_string($input[1], true);
    }

    return preg_replace_callback($regex, 'parseTagsRecursive', $input);
}


$text = "hello [xcode] <? echo bar ?> [/xcode] world and [xcode] <?php phpinfo(); ?> [/xcode]";

echo parseTagsRecursive($text);

The output of parsing the $text variable through this function is:

hello  <? echo bar ?>  world and  <?php phpinfo(); ?>  

Thank you everyone for input!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜