У меня довольно простая ситуация, у меня есть массив строк, и я хочу найти все совпадения для них в одной строке и разместить вокруг них сильные теги. Это то, что у меня есть до сих пор:
$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';
Второй – более элегантный (и быстрее – также ускоряет поиск, держу пари), но не позволяет вам использовать частичные замены слов.