preg_replace中的preg_replace

时间:2018-02-26 06:53:13

标签: php regex preg-replace preg-match

现在我在更换已经从preg_match发出的字符串时遇到了问题。假设我有[b]bla[/b]的bb代码,我已将此部分用[b]替换为<b>,但我们只是为了所有测试目的而说[b]hi [b]test[/b][/b],结束了什么出来的是&#34; hi [b]test[/b]&#34;,所有内容都以粗体显示,但[b]因某些原因不会被替换。

目前这是我的表达:/\[b\](.*)\[\/b\]/

抱歉,我没有显示我的代码,我是新手。

// Will convert string data into readable data
function ConvertStringData2ReadableData($UglyString) {

$CheckArrays = [
"QUOTE" => "/\[quote=?(.*)\](.*)\[\/quote\]/",
"BOLD" => "/\[b\](.*)\[\/b\]/",
"ITALIC" => "/\[i\](.*)\[\/i\]/",
];

$FanceString = $UglyString;

// QUOTES
do {
    $FanceString = preg_replace_callback(
        $CheckArrays['QUOTE'],
        function($match) {
            if (is_numeric($match[1])) {
                $TPID = GetThreadPoster($match[1]);
                $TPUN = GetUsernameS($TPID);
                $statement = ('<div class="panel panel-default"><div class="panel-heading">'.$match[2].'<br>- <b>'.$TPUN.'</b></div></div>');
            } elseif (!is_numeric($match[1])) {
                $statement = ('<div class="panel panel-default"><div class="panel-heading">'.$match[2].'</div></div>');
            }
            return $statement;
        },
        $FanceString,
        -1,
        $count
    );
} while ($count > 0);

// BOLD
do {
    $FanceString = preg_replace($CheckArrays['BOLD'] , "<b>$1</b>" , $FanceString, -1, $count);
} while ($count > 0);
#$FanceString = preg_replace($CheckArrays['BOLD'] , "<b>$1</b>" , $FanceString, -1);

// ITALIC
do {
    $FanceString = preg_replace($CheckArrays['ITALIC'] , "<i style='all: unset; font-style: italic;'>$1</i>" , $FanceString, -1, $count);
} while ($count > 0);

return($FanceString);

}

1 个答案:

答案 0 :(得分:0)

因为你永远无法完全信任用户数据,并且因为bbcode和html一样容易被正则表达式解析,所以你永远不会100%确信这个方法会起作用。 非引用标记可以很容易地被非正则表达式方法替换,所以我通过对逻辑进行分段来消除模式卷积。

我正在为引号标签实现一个递归模式(假设一切都会平衡)并使用你的do-while()技术 - 我认为这是最好的方法。这将在每次迭代时从内向引号有效地起作用(而$count是正的)。

代码:(Demo

function bbcodequote2html($matches){
    $text=(isset($matches[2])?$matches[2]:'');  // avoid Notices
    if(isset($matches[1]) && ctype_digit($matches[1])){
        $TPID = "#{$matches[1]}"; // GetThreadPoster($match[1]);
        $TPUN = "#{$matches[1]}"; // GetUsernameS($TPID);
        $quotee="<br>- <b>$TPUN</b>";
    }else{
        $quotee='';  // no id value or id is non-numeric default to empty string
    }
    return "<div class=\"panel panel-default\"><div class=\"panel-heading\">$text$quotee</div></div>";
}

$bbcode=<<<BBCODE
[quote=2]Outer Quote[b]bold [b]nested bold[/b][/b]
[i]italic [i]nested italic[/i][/i][quote]Inner Quote 1: (no id)[/quote]
[quote=bitethatapple]Inner Quote 2[quote=1]Inner Quote 3[/quote] still inner quote 2 [quote=mickmackusa]Inner Quote 4[/quote] end of inner quote 2[/quote][/quote]
BBCODE;

$converted=str_replace(
    ['[b]','[/b]','[i]','[/i]'],
    ['<b>','</b>','<i style=\"all:unset;font-style:italic;\">','</i>'],
    $bbcode
);

$tabs="\t";
do{
    $converted=preg_replace_callback('~\[quote(?:=(.+?))?]((?:(?R)|.*?)+)\[/quote]~is','bbcodequote2html',$converted,-1,$count);
}while($count);

echo $converted;

我很难以易于阅读的方式显示输出。您最好在服务器上运行我的代码,并检查结果是否符合要求。

输出:

<div class="panel panel-default"><div class="panel-heading">Outer Quote<b>bold <b>nested bold</b></b>
<i style=\"all:unset;font-style:italic;\">italic <i style=\"all:unset;font-style:italic;\">nested italic</i></i><div class="panel panel-default"><div class="panel-heading">Inner Quote 1: (no id)</div></div>
<div class="panel panel-default"><div class="panel-heading">Inner Quote 2<div class="panel panel-default"><div class="panel-heading">Inner Quote 3<br>- <b>#1</b></div></div> still inner quote 2 <div class="panel panel-default"><div class="panel-heading">Inner Quote 4</div></div> end of inner quote 2</div></div><br>- <b>#2</b></div></div>