You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

实现搜索关键词前后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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:42:42