【问题标题】:preg_replace within the preg_replacepreg_replace 中的 preg_replace
【发布时间】:2018-02-26 06:53:12
【问题描述】:

现在我在替换 preg_match 中已经出现的字符串时遇到了问题。假设我有 [b]bla[/b] 的 bbcode,我有这部分正在使用 <b> 替换 [b],但我们只是说出于所有测试目的他们做了 [b]hi [b]test[/b][/b],最终出来的是“hi [b]test[/b] ",所有内容都以粗体显示,但 [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);

}

【问题讨论】:

  • 显示一些代码!
  • 请描述或向我们展示您的一些代码
  • 为什么不使用\[(\/?)b\] =&gt; '&lt;$1b&gt;'(它不会处理丢失的右括号)
  • @Justinas 我真的不知道为什么我不知道,但我没有
  • @M0ns1f 抱歉,我正在尝试找到正确显示代码的方法,现已修复。

标签: php regex preg-replace preg-match


【解决方案1】:

你可以这样做:

$string = '[b]hi [b]test[/b][/b]';    
do {
    $string = preg_replace('/\[b\](.*)\[\/b\]/', '<b>$1</b>', $string, -1, $count);
} while ($count > 0);

或者,如果可以将所有 [b] 替换为 &lt;b&gt;[/b] 替换为 &lt;/b&gt; (无论它们的顺序是否正确/成对),或者只是使用 @Justinas 的想法(来自您的 OT 的评论) .

编辑:您还需要将报价正则表达式更改为:

/\[quote(?:=(\d+))?\](.*)\[\/quote\]/s

s 标志允许. 匹配换行符(您可能也想将其添加到其他行)。我还修复了报价 ID 捕获部分。

【讨论】:

  • 所以看起来它可以与此一起使用,但如果您参考我上面发布的代码,不幸的是,这与函数的引号部分无法正常工作。这最终是结果:puu.sh/zvVlI/712e9c08e6.png 来自以下字符串 pastebin.com/raw/WaiTYBDu
  • 好吧,如果没有原始代码,我们无法猜测 :) 今晚会尝试再试一次,但届时可能会有人帮助你。
【解决方案2】:

因为您永远无法完全信任用户数据,并且由于 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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 2013-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多