当今的高亮关键字的做发通常是简单的replace,简单的replace会在如下情况下出错。

多关键字,并且其中有关键字是别的关键字的子集。
多关键字,并且有非第一个关键字存在于替换tag之中。

我采用对关键字按长排序,然后第一次对有子集的关键字转义,第一次替换替换的是转义后的关键字,第二次替换回来。这样保证了
替换后的无错。需要说明的是,效率很低。

详细代码如下

<style>
body{font
-size:14px;}
</style>
<?php
require_once("iecho.php");

$time1 = getmicrotime();

$string = "Kaspersky 。 Kaspersky 认了 Kaspersky ";

$findKeyArr=array(  "font"  , "red" , "stop" , "kasper" , "s" , "p" );
arsortByLen( 
$findKeyArr , "DESC" );
//prt($findKeyArr);
highlightString( $string , $findKeyArr );
echo $string."<br>";

//把数组按值的长度排序
//作者 异域苍穹(gudai)
//版权所有,如需使用,必须注明作者来源。

function arsortByLen(&$arr , $mode="ASC" )
{
    
foreach$arr as $k=>$v)
    {
        
$len[$k= strlen($v);
    }
    
if$mode=="ASC" )
        
asort($len);
    
elseif$mode=="DESC" )
        
arsort($len);

    
foreach$len as $k=>$v)
    {
        
$newarr[] = $arr[$k];
    }
    
$arr = $newarr;
}

//高亮关键字
//作者 异域苍穹(gudai)
//版权所有,如需使用,必须注明作者来源。
function highlightString(&$string , $findKeyArr ,$highlightTagStart="<font color=red>", $highlightTagEnd="</font>" )
{

    
$start = "[[<<{{";
    
$end = "}}>>]]";

    
$st = $highlightTagStart;
    
$se = $highlightTagEnd;
    
$break = "~~~~";

    
$keystring = ";".implode(";",$findKeyArr).";";

    
//转义一次
    foreach$findKeyArr as $k)
    {
        
//echo $keystring."    ->    $k<br>";
        $tmp = str_replace(";$k;",";####;",$keystring);
        
$tmp = str_replace$k , $break.$k , $tmp );
        
$keystring = str_replace"####;" , "$k;" , $tmp );
    }

    
$keystring = substr($keystring,1,-1);
    
$newkeyarr=explode(";",$keystring);
    
    
//替换key
    foreach$findKeyArr as $k=>$key)
    {
        
$reg = "#([^~]{4}|^)".$key."#i";
        
$newkey = $newkeyarr[$k];
        
$string = preg_replace($reg, "\\1".$start.$newkey.$end,$string);
        
//$newkey['repl'][] = 保留大小写.
    }
    
    
//echo $string."    1<br>";
    
    //把防重复替换的唯一key替换回去

    foreach$newkeyarr as $k=>$key)
    {
        
$oldkey = $findKeyArr[$k];
        
$string = str_replace$key , $oldkey , $string );
    }

    
$string = str_replace($start,$st,$string);
    
$string = str_replace($end,$se,$string);

}


$time1End = getmicrotime();
echo ($time1End-$time1)."<br>\n";
?>