【问题标题】:how to highlight search results如何突出显示搜索结果
【发布时间】:2012-04-25 09:57:53
【问题描述】:

你好,我有一个搜索功能,我将在数据库中搜索关键字。我想突出显示关键字并找到我想在搜索功能中实现的第二个功能。

所以我有这个搜索代码:

<?php 
function searchText($keywords){
    global $db;
    $returned_results = array();
    $where2 = "";

    $keywords = preg_split('/[\s]+/', $keywords); 
    $total_keywords = count($keywords);

    foreach ($keywords as $key=>$keyword){
        $where2 .= "`column` LIKE '%$keyword%'";

        if ($key != ($total_keywords - 1)){ 
            $where2 .= " OR ";
        }
    }

    $results_text = "SELECT `a`, `b`, LEFT(`c`, 150) as `c` FROM `table` WHERE $where2"; 
    $results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0; 
    if ($results_num_text === 0){
        return false;
    } else {

        while ($row = mysqli_fetch_assoc($query2)){

            $returned_results[] = array(
                'ab' => $row['ab'],
                'cd' => $row['cd'], 
            );
        }

        return $returned_results;
    }
}
?>

并希望在其中实现第二个功能:

<?php
function mark_words ($text, $words, $colors = false)
{

    if (!$colors || !is_array($colors) ) {
        $colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99');
    }

    $c = 0;

    foreach ($words as $w) {

        $w = preg_quote(trim($w));

        if($w=='') {
            continue;
        }

        $regexp = "/($w)(?![^<]+>)/i";

        $replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>';

        $text = preg_replace ($regexp,$replacement ,$text);

        $c++;
        if ($c >= count($colors)) {
            $c=0;
        }
    }
    return $text;
}

$example = <<< EOT
some text is here inside
EOT;

$search = array('some','is', 'inside');

echo mark_words($example, $search);
?> 

所以我有这段代码不起作用:

<?php 
function searchText($keywords, $colors = false){
    global $db;

     if (!$colors || !is_array($colors) ) {
        $colors = array('#ff9999', '#ffff99', '#ff99ff', '#99ffff','#99ff99');
    }

    $c = 0;

    $returned_results = array();
    $where2 = "";

    $keywords = preg_split('/[\s]+/', $keywords); 
    $total_keywords = count($keywords);

    foreach ($keywords as $key=>$keyword){

    $regexp = "/($w)(?![^<]+>)/i";
        $replacement = '<b style="background-color:'.$colors[$c].'">\\1</b>';

        $text = preg_replace($regexp,$replacement ,$keywords);
        $c++;

        if ($c >= count($colors)) {
            $c=0;
        }

        $where2 .= "`b` LIKE '%$keyword%'";

        if ($key != ($total_keywords - 1)){ 
            $where2 .= " OR ";
        }
    }

    $results_text = "SELECT `a`, LEFT(`b`, 150) as `b`, `c` FROM `table` WHERE $where2";
    $results_num_text = ($query2 = mysqli_query($db, $results_text)) ? mysqli_num_rows($query2) : 0; 
    if ($results_num_text === 0){
        return false;
    } else {

        while ($row = mysqli_fetch_assoc($query2)){

            $returned_results[] = array(
                'ab' => $row['a'],
                'cd' => $row['b'],
            );
        }

        return $returned_results;
        $highlight = array($keywords);
        echo mark_words($highlight);
    }
}
?>

当我寻找它时,我发现了两种可能性。第一个是一个函数,第二个是直接从选择查询中突出显示它:

SELECT
        REPLACE(`col`, 'foobar', '<span class="highlight">foobar</span>') AS `formated_foobar`
  FROM
        …
  WHERE
        `col` LIKE "%foobar%"

所以我的问题是如何在搜索功能中实现第二个功能,还是使用第二种方法更好?

如果有人可以帮助我,我将不胜感激。非常感谢。

【问题讨论】:

  • 您的\\1 将直接打印\1。要使用存储的值,您需要\1$1
  • 你好,还是不行。

标签: php mysql html function syntax-highlighting


【解决方案1】:

你不应该让自己太难。您只需要用应用了所需样式的跨度中包含的单词替换每个出现的单词。这应该适合你:

function highlight_word( $content, $word, $color ) {
    $replace = '<span style="background-color: ' . $color . ';">' . $word . '</span>'; // create replacement
    $content = str_replace( $word, $replace, $content ); // replace content

    return $content; // return highlighted data
}

function highlight_words( $content, $words, $colors ) {
    $color_index = 0; // index of color (assuming it's an array)

    // loop through words
    foreach( $words as $word ) {
        $content = highlight_word( $content, $word, $colors[$color_index] ); // highlight word
        $color_index = ( $color_index + 1 ) % count( $colors ); // get next color index
    }

    return $content; // return highlighted data
}



// words to find
$words = array(
    'normal',
    'text'
);

// colors to use
$colors = array(
    '#88ccff',
    '#cc88ff'
);

// faking your results_text
$results_text = array(
    array(
        'ab'    => 'AB #1',
        'cd'    => 'Some normal text with normal words isn\'t abnormal at all'
    ), array(
        'ab'    => 'AB #2',
        'cd'    => 'This is another text containing very normal content'
    )
);

// loop through results (assuming $output1 is true)
foreach( $results_text as $result ) {
    $result['cd'] = highlight_words( $result['cd'], $words, $colors );

    echo '<fieldset><p>ab: ' . $result['ab'] . '<br />cd: ' . $result['cd'] . '</p></fieldset>';
}

使用正则表达式替换内容也可以,不过使用str_replace() 会快一些。

函数接受这些参数:

highlight_word( string, string, string );

highlight_words( string, array, array );

上面的例子结果:

【讨论】:

  • 您好,感谢您的回答。我理解这一点,但不知道如何将其实现到返回的结果数组,该数组将由 if ($output1 == true){ foreach ($results_text as $result){ echo "

    " 回显。" ab:".$result['ab']."
    " ."cd: ".$result['cd']."
    "} 和 in cd 应该是突出显示的关键字。

  • 如果您使用跨度,请使用类而不是硬编码这样的值;)
  • 我在理解 $results_text 时遇到问题。我是这样理解的,里面的数组将是来自搜索函数的数组,还是?所以我不能说会有多少个数组。所以它实际上是:$results_text = (searchText($keywords)) 但是我怎样才能得到特定的数组键'ab'来突出显示呢?
  • 使用 $results_text = array(searchText($keywords));回显错误消息:致命错误:函数名称必须是...中的字符串
  • 你应该使用$results_text = searchText( $keywords ); 之后你可以使用我的foreach循环。 foreach( $results_text as $result ) 等等...
【解决方案2】:

通过使用 str_ireplace 代替 str_replace,该函数将不区分大小写

【讨论】:

    【解决方案3】:

    我不会使用 SQL 方法。随着时间的推移,你有越来越多的突出规则,这将变得难以管理。处理需要以不同于 foobar 的方式突出显示 foo 的情况也更棘手,但其中一个包含另一个。

    将数据处理与格式分开。

    【讨论】:

      猜你喜欢
      • 2017-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-16
      • 2021-07-24
      • 2015-09-09
      • 2014-03-07
      • 2014-07-25
      相关资源
      最近更新 更多