我在PHP中使用此功能,用于突出显示给定字符串中的搜索词:
function highlight_match($h, $text_to_search){
foreach($h as $pattern){
$text_to_search = preg_replace("/($pattern)/i", "<span class=\"highlight_match\">$1</span>", $text_to_search);
}
return $text_to_search;
}
使用这样的功能可以正常工作:
$h = array(
'peter',
'bell'
);
$text_to_search = 'peter pan likes tinker bell'
echo highlight_match($h, $text_to_search);
// results: <span class="highlight_match">peter</span> pan likes tinker <span class="highlight_match">bell</span>
当搜索项包含上一次迭代中刚刚替换(添加)的部分内容时,就会出现问题,如下例所示:
$h = array(
'pan',
'bell'
);
$text_to_search = 'peter pan likes tinker bell'
echo highlight_match($h, $text_to_search);
// results: peter <s<span class="highlight_match">pan</span> class="highlight_match">pan</s<span class="highlight_match">pan</span>> likes tinker <span class="highlight_match">bell</span>
这是因为该函数正在迭代要查找的术语列表,因此第二个+迭代可以具有&lt; span class =“highlight_match”&gt; ..&lt; / span&gt;如果当前迭代的搜索项匹配给定字符串中的任何内容(包括我们刚刚在上一次迭代中添加的任何文本/ html),它将被替换。
我不确定如何解决这个问题。是否有功能/方法一次完成字符串上的所有不同匹配/替换?
答案 0 :(得分:2)
您可以将所有字符串放入一个模式中:
$highlighted = preg_replace(
"/(peter|pan)/i",
"<span class=\"highlight_match\">$1</span>",
$text_to_search);
在这种情况下,模式(peter|pan)
表示“ peter 或 pan ”。
还有另一种解决方案比简单的 OR 模式更灵活。如果你真的需要一个接一个地应用你的替代品,它就有效。
它分两步完成:首先你像以前一样替换文本,但是你不插入<span>
,而是一个永远不会匹配你的模式的占位符。在第二步中,将占位符替换为实际的突出显示标记:
$replace = array('pan', 'bell');
$text_to_search = 'peter pan likes tinker bell';
$delim = 'yB9oMjDWpMy'; // just a random string; must not match your patterns
$tags = array(
"open_$delim" => '<span class="highlight">',
"close_$delim" => '</span>'
);
foreach ($replace as $term)
{
$text_to_search = preg_replace(
"/($term)/i",
sprintf('open_%1$s$1close_%1$s' , $delim),
$text_to_search);
}
// intermediate result:
// peter open_yB9oMjDWpMypanclose_yB9oMjDWpMy likes tinker open_yB9oMjDWpMybellclose_yB9oMjDWpMypeter pan likes tinker bell
$text_to_search = str_replace(
array_keys($tags),
array_values($tags),
$text_to_search);
// final result
// peter <span class="highlight">pan</span> likes tinker <span class="highlight">bell</span>
这有点复杂,但它允许使用更多种类的正则表达式模式。