I have to replace the last match of a string (for example the word foo) in HTML document. The problem is that the structure of the HTML document is always random.
I'm trying to accomplish that with preg_replace, but so far I know how to replace only the first match, but not the last one.
Thanks.
Use negative look after (?!...)
$str = 'text abcd text text efgh';
echo preg_replace('~text(?!.*text)~', 'bar', $str),"\n";
output:
text abcd text bar efgh
A common approach to match all text to the last occurrence of the subsequent pattern(s) is using a greedy dot, .*
. So, you may match and capture the text before the last text
and replace with a backreference + the new value:
$str = 'text abcd text text efgh';
echo preg_replace('~(.*)text~su', '${1}bar', $str);
// => text abcd text bar efgh
If text
is some value inside a variable that must be treated as plain text, use preg_quote
to ensure all special chars are escaped correctly:
preg_replace('~(.*)' . preg_quote($text, '~') . '~su', '${1}bar', $str)
See the online PHP demo and a regex demo.
Here, (.*)
matches and captures into Group 1 any zero or more chars (note that the s
modifier makes the dot match line break chars, too), as many as possible, up to the rightmost (last) occurrence of text
. If text
is a Unicode substring, the u
modifier comes handy in PHP (it enables (*UTF)
PCRE verb allowing parsing the incoming string as a sequence of Unicode code points rather than bytes and the (*UCP)
verb that makes all shorthand character classes Unicode aware - if any).
The ${1}
is a replacement backreference, a placeholder holding the value captured into Group 1 that lets restore that substring inside the resulting string. You can use $1
, but a problem might arise if the $text
starts with a digit.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With