preg_replace 中的 preg_replace [英] preg_replace within the preg_replace

查看:65
本文介绍了preg_replace 中的 preg_replace的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

现在我在替换已经从 preg_match 出来的字符串时遇到了问题.假设我有 [b]bla[/b] 的 bbcode,我有这部分工作用 替换 [b]>,但让我们就所有测试目的说他们做了[b]hi [b]test[/b][/b],结果是hi [b]test[/b]",所有内容都以粗体显示,但 [b] 由于某种原因不会被替换.

Right now I'm having issues replacing strings that already come out from preg_match. Lets say I have bbcode of [b]bla[/b], I have this part working with replacing [b] with <b>, but lets just say for all testing purposes that they did [b]hi [b]test[/b][/b], what ends up coming out is "hi [b]test[/b]", with everything being bolded, but the [b] won't get replaced for some reason.

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

抱歉,我没有展示我的代码,我是新手.

Sorry, I didn't show my code, I'm new to this.

// 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);

}

推荐答案

因为您永远无法完全信任用户数据,而且 bbcode 与 html 一样容易受到正则表达式错误解析的影响,所以您永远不会是 100% 相信此方法会奏效.非引号标签可以很容易地被非正则表达式方法替换,所以我通过分割逻辑来消除模式卷积.

Because you are never going to be able to fully trust user data AND because bbcode is just as vulnerable as html to incorrect parsing by regex, you will never be 100% confident that this method will work. Non-quote tags can just as easily be replaced by a non-regex method, so I am eliminating the pattern convolution by segmenting the logic.

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

I am implementing a recursive pattern for quote tags (assuming everything will be balanced) and using your do-while() technique -- I think this is the best approach. This will effectively work from outer quote inward on each iteration (while $count is positive).

代码:(演示)

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;

我很难以易于阅读的方式显示输出.您最好在您的服务器上运行我的代码并检查结果是否按预期呈现.

It is difficult for me to display the output in a fashion that is easy to read. You may be best served to run my code on your server and check that the results render as desired.

输出:

<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>

这篇关于preg_replace 中的 preg_replace的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆