Php 用preg_replace_回调和str_replace替换文本

Php 用preg_replace_回调和str_replace替换文本,php,regex,Php,Regex,好的,我正在尝试替换我的网站评论部分中使用bbcode的长引号,我正在尝试将长引号封装在一个折叠中,我已经用js和css编码过了 我的问题是它会引用第一个引号,然后其他引号消失。我显然遗漏了一些东西,但这是我第一次使用这样的回调 下面是我的php代码: $body = preg_replace_callback("/\[quote\](.*?)\[\/quote\]/is", function($matches) { if (strlen($matches[1]) >= '1000

好的,我正在尝试替换我的网站评论部分中使用bbcode的长引号,我正在尝试将长引号封装在一个折叠中,我已经用js和css编码过了

我的问题是它会引用第一个引号,然后其他引号消失。我显然遗漏了一些东西,但这是我第一次使用这样的回调

下面是我的php代码:

$body = preg_replace_callback("/\[quote\](.*?)\[\/quote\]/is",
function($matches)
{
    if (strlen($matches[1]) >= '1000')
    {
        $matches[0] = str_replace($matches[0], '<div class="box"><div class="collapse_container"><div class="collapse_header"><span>Long quote, click to expand</span></div><div class="collapse_content">' . $matches[1] . '</div></div></div>', $matches[0]);
        return $matches[0];
    }
}, $body);

默认情况下,Phps preg*函数的行为是贪婪的。它们将匹配正则表达式描述的最长字符串。在您的例子中,正则表达式计算从第一个[quote]到最后一个[quote]的所有内容。要改变此行为,必须使用“U”修饰符:

$body = preg_replace_callback("/\[quote\](.*?)\[\/quote\]/isU",...);

有关修饰符列表,请参见您需要将返回值
$matches[0]
代码移到
if
块之外:

function($matches)
{
    if (strlen($matches[1]) >= '1000') {
        $matches[0] = str_replace($matches[0], '<div class="box"><div class="collapse_container"><div class="collapse_header"><span>Long quote, click to expand</span></div><div class="collapse_content">' . $matches[1] . '</div></div></div>', $matches[0]);
    }
    return $matches[0];
}
参见(30个步骤)和(2025个步骤)


请参见

这不起作用,因为它将全文中的第一个[quote]与最后一个[quote]相匹配。您误读了
U
修饰符的作用。PHP正则表达式在默认情况下不是“贪婪的”<默认情况下,code>*是贪婪的,
使其懒惰。
U
反转
*
*?
配对。只需移动
返回$matches[0]
ìf
块之外。@Liam Dawe我是该库的作者,该库设计用于处理任何类型的短代码和bbcode。请看一看,它肯定会帮助您的用例:。如果你需要任何帮助,只要打开一个问题,我会帮你。
function($matches)
{
    if (strlen($matches[1]) >= '1000') {
        $matches[0] = str_replace($matches[0], '<div class="box"><div class="collapse_container"><div class="collapse_header"><span>Long quote, click to expand</span></div><div class="collapse_content">' . $matches[1] . '</div></div></div>', $matches[0]);
    }
    return $matches[0];
}
'~\[quote\]([^[]*(?:\[(?!/quote\])[^[]*)*)\[/quote\]~i'