Функция PHP preg_replace заменяет предыдущие совпадения

У меня довольно простая ситуация, у меня есть массив строк, и я хочу найти все совпадения для них в одной строке и разместить вокруг них сильные теги. Это то, что у меня есть до сих пор:

$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); 

Проблема в том, что функция preg_replace, похоже, соответствует поисковому запросу «s» по отношению к сильным тегам по мере их замены. Поэтому я заканчиваю:

<strong> Thisstrong> – это <strong> teststrong>.

Когда я действительно хочу:

<strong> Этот </ strong> i <strong> s </ strong> тест <strong> </ strong>.

Итак, вы можете предложить мне, где я ошибаюсь?

Любая помощь очень ценится, я отрываю свои волосы от этого, и я должен быть рядом.

Вы не хотите выполнять три замены, но одно:

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

Редактирование hakre: Это работает так или иначе. Первый матч будет выполнен. Поэтому начните с самой длинной строки и возьмите самую маленькую строку в качестве последней.

ответ двоичного кода на это редактирование: см. комментарии


Полная версия:

 <?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); с <?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); 

Простейших способов гарантировать это не будет, чтобы использовать два специальных «faketags», которые не могут быть заменены, а затем заменить их или указать, что слова должны быть полным совпадением слов и начинаться и заканчиваться на границе слова ,

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

или

  $searchWords[$i] = '/\b'.preg_quote($searchWords[$i]).'\b/i'; 

Второй – более элегантный (и быстрее – также ускоряет поиск, держу пари), но не позволяет вам использовать частичные замены слов.