原因是这样的,公司在做搜索时,比如文件名搜索,要求后端在返回时把文件名上能匹配到的文字加上标签。
比如,搜索haha,如果返回的文件名是haha123.jpg,那么后端返回时就为
这个操作其实php有函数能处理:
$searchName = "haha";
$fileName = "hahabb123.jpg";
$formatKeywords = htmlspecialchars($searchName);
$FileName = str_replace("{$searchName}", "<highlight>{$formatKeywords}</highlight>", $fileName);
但这种又有新的问题,虽然能批量处理,但客户想要的是我搜索Haha,也能匹配。其实mysql在搜索时是不区分大小写的。但 str_replace
区分大小写。当然也可以用 str_ireplace
不区分大小写,但如果客户搜索HaHA,通过str_ireplace
操作后返回的就是
那么要满足这个需求,就得另写方法了。
通过一系列搜索,主要参考这些文章:
https://www.yuque.com/darry/php/fpglfk
https://www.yuque.com/darry/php/drcs1g
https://www.yuque.com/darry/php/vxr0da
最终完成代码如下:
<?php
$str1 = "we你";
$str = "wE你EWhaWE你ha你wwe你好We你C谙WeheatwE你.jpg";
echo replaceHighlightTxt($str, $str1, "strong");
/**
* 给一个字符串中查找到的字符串加标签
* @author darry
* @datetime 2021/3/22 17:49
* @param string $string
* @param string $search
* @param string $tag
* @return string
*/
function replaceHighlightTxt(string $string = "", string $search = "", string $tag = "highlight"): string
{
$resStr = $string;
$posArr = getCharPos2($string, $search);
if (empty($posArr)) {
return $resStr;
}
$firstTag = "<" . $tag . ">";
$endTag = "</" . $tag . ">";
$firstTagLen = strlen($firstTag);
$endTagLen = strlen($endTag);
$len = strlen($search);
$i = 0;
foreach ($posArr as $index) {
$firstIndex = $index + $i * ($firstTagLen + $endTagLen);
$resStr = substr_replace($resStr, $firstTag, $firstIndex, 0);
$endIndex = $firstIndex + $firstTagLen + $len;
$resStr = substr_replace($resStr, $endTag, $endIndex, 0);
$i++;
}
return $resStr;
}
/**
* 获取一字符串在另一字符串中所有位置
* @param string $str
* @param string $char
* @return array
* @author darry
* @datetime 2021/3/22 15:01
*/
function getCharPos2(string $str, string $char): array
{
$j = 0;
$arr = [];
//全转成小写,来达到不区分大小写的目的
$checkStr = strtolower($str);
$checkChar = strtolower($char);
//一个字符串在另一个字符串中出现的次数
$count = substr_count($checkStr, $checkChar);
for ($i = 0; $i < $count; $i++) {
$j = strpos($checkStr, $checkChar, $j);
$arr[] = $j;
$j = $j + 1;
}
return $arr;
}
结果如下: