MortenMoulder
MortenMoulder

Reputation: 6648

str_replace or preg_replace only replacing last match?

I want to replace the final </body> tag on a page of HTML. There are many tags on the page (because of iFrames) so I need to replace only the last.

For example, if I had this code:

</body>
</body>
</body>
</body>

I need to replace the last </body> tag with something else.

I have tried to do preg_replace("~(?!.*</body>)~",$replace_with,$content); but it didn't work so well.

Any ideas?

Upvotes: 2

Views: 1491

Answers (1)

HamZa
HamZa

Reputation: 14921

We will exploit the greedy quantifier and use one advanced technique:

~.*\K</body>~s

Some explanation:

~        # A simple delimiter
.*       # Match anything greedy (until the end)
\K       # Forget what we matched until now
</body>  # Match ¨</body>¨
~        # The closing delimiter
s        # The s modifier to also match newlines with the dot ¨.¨

The PHP implementation could look like this:

$str = '
</body>
Something !
</body>
</body>
</body>
</body>
</html>';

$search = '</body>';
$replace = '</replaced>';

$str = preg_replace('~.*\K'. preg_quote($search, '~') . '~s', '$1' . $replace, $str);

echo $str;

Note that we used preg_quote() to escape appropriate characters that might be used from untrusted users.

Output:

</body>
Something !
</body>
</body>
</body>
</replaced>
</html>

Upvotes: 4

Related Questions