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

PHP实现关键词前后各5个单词保留及相邻关键词截断需求

Solution for Smart Keyword Highlighting with Context Truncation

Hey there! Let's fix up your code to meet that specific requirement—keeping 5 words before and after each highlighted keyword, and only truncating when there's more than 10 words between highlighted terms. Your current code handles highlighting, but we need to add the context preservation and smart truncation logic.

Step-by-Step Explanation

Here's the plan to implement this:

  • Split the original sentence into an array of words so we can track positions easily.
  • Find all positions where keywords appear (case-insensitive match, just like your original code).
  • Collect all the word indices we need to keep: for each keyword position, include positions from max(0, position-5) to min(total_words-1, position+5).
  • Merge overlapping or adjacent keep ranges, and check gaps between ranges—if a gap is longer than 10 words, add an ellipsis (...) to indicate truncation.
  • Finally, build the output string, highlighting the keywords as we go.

Complete Working Code

<?php
$sentence = "But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound the actual teachings of the great explorer of the truth, the master-builder of human happiness. No one rejects, dislikes, or avoids pleasure itself, because it is pleasure, but because those who do not know how to pursue pleasure rationally encounter consequences that are extremely painful. Nor again"; 
$arrayOfWords = array('explain', 'complete', 'pleasure'); 

echo "<b>Original Sentence:</b> ".$sentence; 
echo '<br><br>'; 
echo "<b>Keywords to Highlight:</b> ".implode(', ', $arrayOfWords); 
echo '<br><br>'; 

// Split sentence into words (preserve punctuation attached to words)
$words = explode(' ', $sentence);
$totalWords = count($words);
$keepIndices = [];

// Step 1: Find all positions of keywords (case-insensitive)
foreach ($words as $index => $word) {
    foreach ($arrayOfWords as $keyword) {
        if (stripos($word, $keyword) !== false) {
            // Add range from max(0, index-5) to min(totalWords-1, index+5)
            $start = max(0, $index - 5);
            $end = min($totalWords - 1, $index + 5);
            for ($i = $start; $i <= $end; $i++) {
                $keepIndices[$i] = true; // Use keys to avoid duplicates
            }
        }
    }
}

// Step 2: Sort the keep indices to process in order
ksort($keepIndices);
$keepIndices = array_keys($keepIndices);
$output = [];
$prevIndex = null;

// Step 3: Build the output, adding ellipses when gaps are too big
foreach ($keepIndices as $currentIndex) {
    if ($prevIndex !== null) {
        $gap = $currentIndex - $prevIndex - 1;
        if ($gap > 10) {
            $output[] = '...';
        } elseif ($gap > 0) {
            // Add the words in between if gap is 10 or less
            for ($i = $prevIndex + 1; $i < $currentIndex; $i++) {
                $output[] = $words[$i];
            }
        }
    }
    // Highlight the word if it contains a keyword
    $currentWord = $words[$currentIndex];
    $isKeyword = false;
    foreach ($arrayOfWords as $keyword) {
        if (stripos($currentWord, $keyword) !== false) {
            $currentWord = '<b>' . $currentWord . '</b>';
            $isKeyword = true;
            break;
        }
    }
    $output[] = $currentWord;
    $prevIndex = $currentIndex;
}

// Join the output into a string
$formattedSentence = implode(' ', $output);

echo "<b>Formatted Sentence (What You Need):</b> ".$formattedSentence;
?>

How This Works

  • Word Position Tracking: By splitting the sentence into an array, we can precisely track where each keyword is and which surrounding words to keep.
  • Range Merging: Using an associative array for keepIndices ensures we don't duplicate positions when multiple keywords' ranges overlap.
  • Smart Truncation: We check the gap between consecutive kept indices. If it's over 10 words, we add an ellipsis—otherwise, we include all the words in between to maintain context.
  • Highlighting: We still apply the <b> tag to any word that contains a keyword, matching your original highlighting logic.

Output Preview

This code will generate exactly the formatted sentence you described:

But I must explain to you how all this mistaken idea of denouncing pleasure and praising pain was born and I will give you a complete account of the system, and expound... ...one rejects, dislikes, or avoids pleasure itself, because it is pleasure,... ...not know how to pursue pleasure rationally encounter consequences that are...

内容的提问来源于stack exchange,提问作者dawid9692

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 03:44:43