[英]preg_replace within the preg_replace
现在,我遇到了替换preg_match已经出现的字符串的问题。 可以说,我有BB代码[b]bla[/b]
我有这部分与更换工作[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);
}
您可以执行以下操作:
$string = '[b]hi [b]test[/b][/b]';
do {
$string = preg_replace('/\[b\](.*)\[\/b\]/', '<b>$1</b>', $string, -1, $count);
} while ($count > 0);
如果可以将所有[b]
替换为<b>
并将[/b]
替换为</b>
则可以使用@Justinas的想法(来自旧约的评论)(无论它们的排列顺序正确/成对)。
编辑 :您还需要将报价正则表达式更改为此:
/\\[quote(?:=(\\d+))?\\](.*)\\[\\/quote\\]/s
s
标志允许.
匹配换行符(您可能也希望将其添加到其他换行符中)。 我还修复了报价ID捕获部分。
因为您将永远无法完全信任用户数据,并且bbcode和html一样容易受到regex错误解析的影响,所以您永远不会百分百确信此方法会起作用。 非引用标记可以很容易地用非正则表达式方法替换,因此我通过分割逻辑来消除了模式卷积。
我正在为报价标签实现一个递归模式(假设所有内容都将保持平衡),并使用您的do-while()
技术-我认为这是最好的方法。 这将有效地在每次迭代中从外引号向内起作用(而$count
为正数)。
代码:( 演示 )
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>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.