preg_replace 变量替换显示单引号错误

preg_replace variable replacement showing error with single quotes

我有这个preg_replace声明,

$s = "Foo money bar";
echo preg_replace("/(office|rank|money)/i", "<strong></strong>", $s);

哪个returns,

Foo <strong>money</strong> bar 

然而,当我尝试用单引号做完全相同的事情并在 $i 上使用一个函数时,它会中断,

$s = "Foo money bar";
echo preg_replace("/(office|rank|money)/i", '<strong>' . ucfirst() . '</strong>', $s);

注意函数第二个参数中的单引号,这现在产生,

syntax error, unexpected '1' (T_LNUMBER), expecting variable (T_VARIABLE) or '{' or '$'

实例

Double Quotes

Single Quotes

所以我的问题是为什么会发生这种情况,以及如何获得第二个示例中所示的预期输出(强 ucfirst)?

更新 #1

发生此问题的原因不仅在于函数 ucfirst,还在于单引号,如 this 示例中所示,

$s = "Foo money bar";
echo preg_replace("/(office|rank|money)/i", '<strong>' .  . '</strong>', $s);

输出

syntax error, unexpected '1' (T_LNUMBER), expecting variable (T_VARIABLE) or '{' or '$'

您不能在 preg_replace 的第二个参数中使用函数。
'<strong>' . ucfirst() . '</strong>' 在搜索之前进行评估。要在正则表达式替换中使用函数,您必须使用 preg_replace_callback:

$result = preg_replace_callback($pattern, function ($m) {
    return '<strong>' . ucfirst($m[1]) . '</strong>';
}, $yourstring);

您收到该错误不是因为引号的类型,而是因为您在引号之外进行操作。

echo preg_replace("/(office|rank|money)/i", "<strong>" .  . "</strong>", $s);

这会抛出同样的错误。那是因为</code>不是一个变量</strong>,而是一个<a href="http://php.net/manual/en/regexp.reference.back-references.php" rel="nofollow noreferrer">back reference</a>。您可以将其称为 <code> 而不是 </code>,这样会更清楚。 </p> <p>所以,你不能引用引号外的反向引用(此外,<code> 将是一个非法的变量名)。我无法参考具体的内部机制来了解它是如何工作的(找不到任何东西),但它可能被设置为 "flag" 供解释器替换为第 n 个匹配组。

有趣的是,如果你使用一个函数作为第二个参数将后面的引用用引号括起来,它仍然有效! (从某种意义上说,它不会出错。它仍然不会 运行 该功能。)

<?php
$s = "Foo money bar";
echo preg_replace("/(office|rank|money)/i", '<strong>' . ucfirst('') . '</strong>', $s); // works with single and double quotes

Demo

This article 没有谈论这个,但无论如何它都是一本很棒的书。