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

时间:2011-10-17 07:48:58

标签: php preg-replace preg-match

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

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

感谢。

4 个答案:

答案 0 :(得分:17)

使用负面看(?!...)

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

<强>输出:

text abcd text bar efgh

答案 1 :(得分:1)

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

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

如果text是必须视为纯文本的变量中的某个值,请使用preg_quoteensure all special chars are escaped correctly

preg_replace('~(.*)' . preg_quote($text, '~') . '~su', '${1}bar', $str)

请参见online PHP demoregex demo

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

(*UCP)是替换后向引用,占位符包含捕获到组1中的值,该值允许在结果字符串中恢复该子字符串。您可以使用${1},但可以使用problem might arise if the $text starts with a digit

答案 2 :(得分:0)

一个例子

<?php

$str = 'Some random text';
$str_Pattern = '/[^ ]*$/';

preg_match($str_Pattern, $str, $results);

print $results[0];

?> 

答案 3 :(得分:0)

当然,这里给出的公认解决方案是正确的。不过,您可能还想查看this帖子。我正在使用这个,不需要模式,字符串不包含所使用的函数无法捕获的字符(即多字节的字符)。我还为dis / about case添加了一个额外的参数。

第一行是:

$pos = $case === true ? strripos($subject, $search) : strrpos($subject, $search);

我必须承认我没有测试性能。但是,我猜 preg_replace()比较慢,特别是在大字符串上。