выделить несколько ключевых слов в поиске - PullRequest
7 голосов
/ 03 мая 2010

Я использую этот код для выделения ключевых слов для поиска:

function highlightWords($string, $word)
 {

        $string = str_replace($word, "<span class='highlight'>".$word."</span>", $string);
    /*** return the highlighted string ***/
    return $string;

 }

 ....

  $cQuote =  highlightWords(htmlspecialchars($row['cQuotes']), $search_result);

однако, это выделяет только одно ключевое слово. если пользователь вводит более одного ключевого слова, он сузит поиск, но ни одно слово не будет выделено. как выделить несколько слов?

Ответы [ 8 ]

25 голосов
/ 03 мая 2010

регулярные выражения - путь!

function highlight($text, $words) {
    preg_match_all('~\w+~', $words, $m);
    if(!$m)
        return $text;
    $re = '~\\b(' . implode('|', $m[0]) . ')\\b~';
    return preg_replace($re, '<b>$0</b>', $text);
}

$text = '
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.
';

$words = 'ipsum labore';

print highlight($text, $words);

Для сопоставления без учета регистра, добавьте 'i' к регулярному выражению

    $re = '~\\b(' . implode('|', $m[0]) . ')\\b~i';

Примечание: для неанглийских букв, таких как "ä", результаты могут отличаться в зависимости от локали.

17 голосов
/ 24 апреля 2015

PHP> 5.3.0, попробуйте preg_filter ()

/**
 * Highlighting matching string
 * @param   string  $text           subject
 * @param   string  $words          search string
 * @return  string  highlighted text
 */
public function highlight($text, $words) {
    $highlighted = preg_filter('/' . preg_quote($words, '/') . '/i', '<b><span class="search-highlight">$0</span></b>', $text);
    if (!empty($highlighted)) {
        $text = $highlighted;
    }
    return $text;
}
6 голосов
/ 03 мая 2010

При условии, что слова введены в виде строки, разделенной пробелами, вы можете просто использовать explode

$words = explode(' ', $term);

Хотя, если вы хотите убедиться, что пробелов не много, вы можете сначала удалить их из строки

$term = preg_replace('/\s+/', ' ', trim($term));
$words = explode(' ', $term);

Затем вам нужно сгенерировать заменяющий массив

$highlighted = array();
foreach ( $words as $word ){
    $highlighted[] = "<span class='highlight'>".$word."</span>"
}

Тогда

str_replace($words, $highlighted, $string);

Так что сложив все вместе

function highlightWords($string, $term){
    $term = preg_replace('/\s+/', ' ', trim($term));
    $words = explode(' ', $term);

    $highlighted = array();
    foreach ( $words as $word ){
        $highlighted[] = "<span class='highlight'>".$word."</span>"
    }

    return str_replace($words, $highlighted, $string);
}
4 голосов
/ 13 июля 2016

выделение нескольких ключевых слов в поиске, включая умлаутс

Я использовал ранее написанное регулярное выражение и заменил \w на [A-Za-z0-9_äöüÄÖÜ]. Как видите, я добавил умлауты äöüÄÖÜ. Я также удалил \b, чтобы он соответствовал любому запросу.

Пример

поисковый запрос:
Су шампунь

Текст:
Солнечный блестящий шампунь

результат:
Su n блестящий шампунь oO


Код, который я использовал:

private function getSearchTermToBold($text, $words)
{
    preg_match_all('~[A-Za-z0-9_äöüÄÖÜ]+~', $words, $m);
    if (!$m)
        return $text;
    $re = '~(' . implode('|', $m[0]) . ')~i';
    return preg_replace($re, '<b>$0</b>', $text);
}
4 голосов
/ 07 августа 2012

вот простая функция для выделения только совпадающего текста.

function highlighter_text($text, $words)
{
    $split_words = explode( " " , $words );
    foreach($split_words as $word)
    {
        $color = "#e5e5e5";
        $text = preg_replace("|($word)|Ui" ,
            "<span style=\"background:".$color.";\"><b>$1</b></span>" , $text );
    }
    return $text;
}

функция вызова

1 голос
/ 23 июля 2012

в соответствии с предложением пользователя 187291, просто измените следующий код, чтобы текст был выделен желтым фоном.

 return preg_replace($re, '<SPAN style="BACKGROUND-COLOR: #ffff00"><b>$0</b></SPAN>', $text); 
0 голосов
/ 17 января 2015

Другие решения могут быть нечувствительны к регистру при поиске основных моментов, но не сохраняют свой регистр исходной строки. Таким образом, поиск «st» найдет «ST», но выделите его как «st», поисковый термин.

Я использую следующее. Сначала он формирует массив замены, а затем использует str_replace () с параметрами массива, что позволяет избежать рекурсии.

function highlightStr($haystack, $needle, $highlightStyle) {

    if (strlen($highlightStyle) < 1 || strlen($haystack) < 1 || strlen($needle) < 1) {
       return $haystack;
    }

    preg_match_all("/$needle+/i", $haystack, $matches);

    $matches[0] = array_unique($matches[0]);

    if (is_array($matches[0]) && count($matches[0]) >= 1) {
        foreach ($matches[0] as $ii=>$match)
            $replace[$ii]="<span style='$highlightStyle'>$match</span>";

        $haystack = str_replace($matches[0], $replace, $haystack);
    }

    return $haystack;
}
0 голосов
/ 03 мая 2010

Разбивает ваш поисковый запрос на слова, затем выделяет каждое слово отдельно.

Хотя лучше выполнить выделение в javascript. Селектор jQuery «содержит», вероятно, поможет избежать проблем с заменой элементов разметки по ходу работы ...

http://api.jquery.com/contains-selector/

...