实现搜索关键词前后n字符截取:优先保留完整单词或允许拆分
自定义搜索结果关键词上下文截取方案
需求说明
- 核心目标:返回搜索关键词左右各
n个字符的内容片段 - 优化规则:优先保留片段首尾的完整单词;若实现难度较高,可接受拆分单词的简化方案
- 效果示例:
原文本:"For example this is the text where I searched the keyword and I need the text around it too."
当n=10时,理想结果:"..searched the keyword and I need.."
可接受结果:"..rched the keyword and I nee.."
当前问题
已编写PHP函数,但无法正确获取关键词前的目标字符串,代码如下:
private function getSubstring($content,$keyword, $nOfChars) { $content = strtolower(strip_tags($content)); $noOffoundStrings = substr_count($content, $keyword); $position = strpos($content, $keyword); $keywordLength = strlen($keyword); $afterKey = substr($content, $position + $keywordLength, $nOfChars); $beforeKey = substr($content, $position , -???); // 无法正确获取关键词前的字符串部分 }
解决方案
基础版(拆分单词,快速实现)
先解决最基础的截取逻辑,通过计算起始位置直接获取关键词前后内容:
private function getSubstring($content, $keyword, $nOfChars) { $content = strtolower(strip_tags($content)); $position = strpos($content, $keyword); // 关键词不存在时返回空 if ($position === false) { return ''; } $keywordLength = strlen($keyword); $contentLength = strlen($content); // 计算关键词前的起始位置,避免出现负数 $beforeStart = max(0, $position - $nOfChars); $beforeKey = substr($content, $beforeStart, $position - $beforeStart); // 获取关键词后的内容 $afterKey = substr($content, $position + $keywordLength, $nOfChars); // 拼接结果并添加省略号 $result = ($beforeStart > 0 ? '..' : '') . $beforeKey . $keyword . $afterKey; if (($position + $keywordLength + $nOfChars) < $contentLength) { $result .= '..'; } return $result; }
此版本直接按字符数截取,可能拆分单词,对应需求中的可接受方案。
进阶版(保留完整单词,优化体验)
通过查找单词边界,实现首尾完整单词的保留:
private function getSubstringWithWholeWords($content, $keyword, $nOfChars) { $content = strtolower(strip_tags($content)); $position = strpos($content, $keyword); if ($position === false) { return ''; } $keywordLength = strlen($keyword); $contentLength = strlen($content); // 处理关键词前的内容:找到最近的单词起始边界 $beforeStart = $position - $nOfChars; if ($beforeStart < 0) { $beforeStart = 0; $beforeKey = substr($content, $beforeStart, $position); } else { // 从起始位置往后找第一个空格,作为单词起始点 $spacePos = strpos($content, ' ', $beforeStart); if ($spacePos !== false && $spacePos < $position) { $beforeStart = $spacePos + 1; } $beforeKey = substr($content, $beforeStart, $position - $beforeStart); } // 处理关键词后的内容:找到最近的单词结束边界 $afterEnd = $position + $keywordLength + $nOfChars; if ($afterEnd > $contentLength) { $afterEnd = $contentLength; $afterKey = substr($content, $position + $keywordLength); } else { // 从结束位置往前找最后一个空格,作为单词结束点 $spacePos = strrpos(substr($content, 0, $afterEnd), ' '); if ($spacePos !== false && $spacePos > $position + $keywordLength) { $afterEnd = $spacePos; } $afterKey = substr($content, $position + $keywordLength, $afterEnd - ($position + $keywordLength)); } // 拼接最终结果 $result = ($beforeStart > 0 ? '..' : '') . $beforeKey . $keyword . $afterKey; if ($afterEnd < $contentLength) { $result .= '..'; } return $result; }
此版本会自动调整截取边界,尽量保留完整单词,符合需求中的理想结果要求。
补充说明
- 加入了关键词不存在的判断逻辑,避免报错
- 基础版逻辑简单,适合对性能要求高的场景;进阶版体验更好,但需要额外的字符串查找操作
- 示例仅处理第一个匹配的关键词,若需处理多个匹配项,可通过循环遍历
strpos的所有结果实现
内容的提问来源于stack exchange,提问作者user805528
相关产品推荐
相关产品推荐

