已经看到了简单的preg_replace (甚至仅仅是str_replace)在搜索单词数组中添加<span class="highlight">的例子。但是,很多搜索查询都会按以下顺序搜索:
搜索:blue shoes
MySQL查询:SELECT * FROM my_table WHERE title LIKE '%blue%shoes%'
比赛:
MATCH --“别踩我的blue绒面shoes”
NO MATCH -“.他的漂亮鞋子和他的婴儿蓝调.”(关键字的顺序不对)
MATCH --“蓝天下的blue shoes”(第二个“蓝色”不应突出显示)
MATCH -“. blue笔记本.她的shoes扔了蓝色的塑料马蹄铁.”
因此,SERP应该以同样的方式突出显示匹配。是否有一种REGEX方法可以按照顺序使用n个搜索项来完成这一任务?还是需要用PHP循环来处理呢?
不正确的尝试:
foreach ( ['blue', 'shoes'] as $term ) {
$result = str_replace($term, "<span style=\"background:yellow\">$term</span>", $title);
}
echo $result;
// This will highlight any instances of "blue" or "shoes" in any order in the result,
// even though the MySQL query searched for those terms in that specific order发布于 2021-11-05 22:39:20
另一个版本使用implode()构建搜索模式,使用preg_replace()执行实际替换:
$haystacks = [
"Don't step on my blue suede shoes",
"... his fancy shoes and his baby blues...",
"blue shoes under the blue sky",
];
$needles = ['blue', 'shoes'];
$format = '<span style="background:red">%s</span>';
function highlightMatches($needles, $haystack, $format)
{
$search = '('.implode(')(.+?)(', $needles).')';
$replace = '';
$gaps_count = count($needles) - 1;
foreach ($needles as $k => $needle) {
$replace .= sprintf($format, '\\'.($k * 2 + 1));
if ($k < $gaps_count) {
$replace .= '\\'.($k *2 + 2);
}
}
return preg_replace("/$search/", $replace, $haystack);
}
foreach ($haystacks as $haystack) {
echo highlightMatches($needles, $haystack, $format)."<br>";
}如果数据库查询可用于编辑,我将尝试使用数据库查询进行突出显示。
发布于 2021-11-05 21:43:25
您提到了mysql,因此在查找所讨论的行时,我将介绍与您的请求非常接近的内容。
WHERE MATCH(col) AGAINST(+"blue shoes" IN BOOLEAN MODE)如果您的问题只涉及PHP代码,那么删除mysql标记。
发布于 2021-11-05 21:34:25
您必须使用PHP生成regexp模式:
function highlightMatches(array $searchTerms, string $string): string {
$result = $string;
foreach ($searchTerms as $i => $term) {
$previous = array_map(function($item) {
return "($item)";
}, array_slice($searchTerms, 0, $i + 1));
$pattern = implode(".+", $previous);
$matches = [];
preg_match("/$pattern/", $string, $matches);
$lastMatch = array_pop($matches);
if ($lastMatch) {
$result = str_replace($lastMatch, "<span style=\"color: red;\">$lastMatch</span>", $result);
}
}
return $result;
}
$searchTerms = ["first", "second", "third"];
$strings = [
"first second third",
"third second first",
"second third first",
"third first second",
];
foreach ($strings as $str) {
echo $str . ":\t" . highlightMatches($searchTerms, $str) . "\n";
}https://stackoverflow.com/questions/69859100
复制相似问题