如何只用preg_replace替换字符串的最后一个匹配?

Dim*_*nov 6 php preg-replace preg-match

我必须在HTML文档中替换字符串的最后一个匹配项(例如单词foo).问题是HTML文档的结构总是随机的.

我试图用preg_replace来实现这一点,但到目前为止我知道如何只替换第一个匹配,但不是最后一个匹配.

谢谢.

Tot*_*oto 18

使用否定的照顾 (?!...)

$str = 'text abcd text text efgh';
echo preg_replace('~text(?!.*text)~', 'bar', $str),"\n";
Run Code Online (Sandbox Code Playgroud)

输出:

text abcd text bar efgh
Run Code Online (Sandbox Code Playgroud)


Wik*_*żew 6

将所有文本与后续模式的最后一次出现匹配的常见方法是使用贪心点, .*。因此,您可以匹配并捕获最后一个之前的文本text,并用反向引用+新值替换:

$str = 'text abcd text text efgh';
echo preg_replace('~(.*)text~su', '${1}bar', $str);
// => text abcd text bar efgh
Run Code Online (Sandbox Code Playgroud)

如果text变量内的某个值必须被视为纯文本,请使用它preg_quote确保所有特殊字符都正确转义

preg_replace('~(.*)' . preg_quote($text, '~') . '~su', '${1}bar', $str)
Run Code Online (Sandbox Code Playgroud)

请参阅在线 PHP 演示正则表达式演示

在这里,将任何零个或多个字符(.*)匹配并捕获s到组 1 中(请注意,修饰符也使点匹配换行符字符),尽可能多,直到最右边(最后一个)出现的text。如果text是 Unicode 子字符串,则u修饰符在 PHP 中很方便(它启用(*UTF)PCRE 动词,允许将传入字符串解析为 Unicode 代码点序列而不是字节,并且该(*UCP)动词使所有速记字符类都识别 Unicode - 如果有的话)。

${1}是一个替换反向引用,一个占位符,保存捕获到组 1 中的值,可以在结果字符串中恢复该子字符串。您可以使用$1,但如果$text以数字开头可能会出现问题。