Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP preg_replace function replacing previous matches

I have a fairly basic situation, I have an array of strings and I want to find all matches for these in a single string and put strong tags around them. This is what I have so far:

$searchWords = array("test","this","s");

for($i=0;$i<sizeof($searchWords);$i++) {
    $searchWords[$i] = "/".preg_quote($searchWords[$i])."/i";
}

$label = "This is a test string.";

$result = preg_replace($searchWords, "<strong>$0</strong>", $label);

echo($result);

The problem is that the preg_replace function seems to be matching the "s" search term against the strong tags as they're replaced. So I'm ending up with:

<strong>Thisstrong> is a <strong>teststrong>.

When what I really want is:

<strong>This</strong> i<strong>s</strong> a <strong>test</strong>.

So, can you guys suggest where I'm going wrong?

Any help is very much appreciated, I'm tearing my hair out over this and I must be close.

like image 700
adc124 Avatar asked May 12 '26 07:05

adc124


1 Answers

You don't want to do three replacements, but one:

$result = preg_replace("#" . implode($searchWords, "|") . "#", "<strong>$0</strong>", $label);

hakre's edit: This works like this or that or that string. The first match will be taken. So start with the longest string and take the smallest string as the last one.

binary's answer on this edit: see comments


Full version:

<?php
$searchWords = array("t", "test", "this");
usort($searchWords, function ($a, $b) { return strlen($b) - strlen($a); });

foreach ($searchWords as &$word)
{
    $word = preg_quote($word);
}
unset($word);

$label = "This is a test string.";

$searchWords = implode($searchWords, "|");
$result = preg_replace("#{$searchWords}#i", "<strong>$0</strong>", $label);

echo($result);
like image 141
binaryLV Avatar answered May 14 '26 22:05

binaryLV