【问题标题】:Function which searches for a word in a text and highlights all the words which contain it在文本中搜索单词并突出显示包含它的所有单词的功能
【发布时间】:2012-05-28 20:21:15
【问题描述】:

此函数在文本中搜索单词(从 $words 数组中)并突出显示它们。

function highlightWords(Array $words, $text){ // Loop through array of words
    foreach($words as $word){ // Highlight word inside original text
        $text = str_replace($word, '<span class="highlighted">' . $word . '</span>', $text);
    }         
    return $text; // Return modified text
}

问题来了:

假设 $words = array("car", "drive");

有没有办法让该功能不仅突出显示单词 car,还突出显示包含字母“car”的单词,例如:cars、carmania 等。

谢谢!

【问题讨论】:

    标签: php


    【解决方案1】:

    你想要的是一个正则表达式,特别是 preg_replace 或 peg_replace_callback (建议在你的情况下使用回调)

    <?php
    $searchString = "The car is driving in the carpark, he's not holding to the right lane.\n";
    
    // define your word list
    $toHighlight = array("car","lane");
    

    因为您需要一个正则表达式来搜索您的字词,并且您可能希望或需要随时间变化或变化,因此将其硬编码到您的搜索字词中是不好的做法。因此,最好使用 array_map 遍历数组并将搜索词转换为正确的正则表达式(这里只是用 / 将其括起来并添加“接受所有内容直到标点符号”表达式)

    $searchFor = array_map('addRegEx',$toHighlight);
    
    // add the regEx to each word, this way you can adapt it without having to correct it everywhere
    function addRegEx($word){
        return "/" . $word . '[^ ,\,,.,?,\.]*/';
    }
    

    接下来,您希望将找到的单词替换为突出显示的版本,这意味着您需要进行动态更改:使用 preg_replace_callback 而不是常规 preg_replace 以便它为找到的每个匹配项调用一个函数并使用它来生成正确的结果.在这里,我们将找到的单词包含在其 span 标签中

    function highlight($word){
        return "<span class='highlight'>$word[0]</span>";
    }
    
    $result = preg_replace_callback($searchFor,'highlight',$searchString);
    
    print $result;
    

    产量

    The <span class='highlight'>car</span> is driving in the <span class='highlight'>carpark</span>, he's not holding to the right <span class='highlight'>lane</span>.
    

    显然,只需将这些代码片段粘贴在另一个之后即可获得工作代码。 ;)

    编辑:下面的完整代码稍作修改 = 放置在例程中,以便原始请求者使用。 + 不区分大小写

    完整代码:

    <?php
    
    $searchString = "The car is driving in the carpark, he's not holding to the right lane.\n";
    $toHighlight = array("car","lane");
    
    $result = customHighlights($searchString,$toHighlight);
    
    print $result;
    
    // add the regEx to each word, this way you can adapt it without having to correct it everywhere
    
    function addRegEx($word){
        return "/" . $word . '[^ ,\,,.,?,\.]*/i';
    }
    
    function highlight($word){
        return "<span class='highlight'>$word[0]</span>";
    }
    
    function customHighlights($searchString,$toHighlight){
    
    // define your word list
    $searchFor = array_map('addRegEx',$toHighlight);
    $result = preg_replace_callback($searchFor,'highlight',$searchString);
    return $result;
    
    }
    

    【讨论】:

    • 非常非常感兴趣...我有一个 funtion.php 文件。我将在那里复制该功能,但不确定将其他部分粘贴到哪里。
    • 我在下面的 1 段中添加了完整的代码供您复制/粘贴 :)
    • 非常感谢,让我试一试 :) 我是一名 seo、Web 开发人员,有时会得到程序员的帮助,真的非常有帮助:)
    • 我想测试一种将函数放在我的functions.php文件中的方法,这样我就可以将代码用于不同的$searchString
    • 我已经修改了完整代码部分,因此您可以使用它:将例程放在您的函数文件中,然后您可以调用 customHighlights($searchString,$toH​​ighlight);显然是 searchString 和要突出显示的数组单词。通常,最好/更容易将它们排除在功能之外并包含在您包含的 1 个文件中。编辑:我将其添加到“完整代码”中
    【解决方案2】:

    我还没有测试过,但我认为应该这样做:-

    $text = preg_replace('/\W((^\W)?$word(^\W)?)\W/', '<span class="highlighted">' . $1 . '</span>', $text);
    

    这会在一个完整的有界词中查找字符串,然后使用 preg_replace 和正则表达式将跨度放置在整个字符串中。

    【讨论】:

    • 让我测试一下,我是个新手,一百万年都不会想到这一点:)
    • 当心,我只是将 'w' 更改为 'W' 以捕捉单词边界!
    • 嗯,dreamweaver 说 php 语法有问题
    • @webmasters 这不适用于单引号,您需要用双引号替换它们,以便使用 $word 值:"/\W((^\W)?$word(^\W)?)\W/"
    • 注意:此正则表达式不支持 UTF-8 - \W 等同于 [^a-zA-Z0-9_]。有关 UTF-8 感知边界的讨论,请参阅stackoverflow.com/questions/4739880/…
    【解决方案3】:
    function replace($format, $string, array $words)
    {
        foreach ($words as $word) {
            $string = \preg_replace(
                sprintf('#\b(?<string>[^\s]*%s[^\s]*)\b#i', \preg_quote($word, '#')),
                \sprintf($format, '$1'), $string);
        }
        return $string;
    }
    
    
    // courtesy of http://slipsum.com/#.T8PmfdVuBcE
    $string = "Now that we know who you are, I know who I am. I'm not a mistake! It
    all makes sense! In a comic, you know how you can tell who the arch-villain's
    going to be? He's the exact opposite of the hero. And most times they're friends,
    like you and me! I should've known way back when... You know why, David? Because
    of the kids. They called me Mr Glass.";
    
    echo \replace('<span class="red">%s</span>', $string, [
        'mistake',
        'villain',
        'when',
        'Mr Glass',
    ]);
    

    因为它对周围的字符串使用sprintf 格式,您可以相应地更改替换。

    请原谅 5.4 语法

    【讨论】:

    • 非常喜欢。这是否适用于上限,例如拉反派和反派?
    • @webmasters Yeop,不区分大小写(这是 i 表达式末尾的修饰符 ...\b#i
    • 记住; $format 参数需要“%s”才能工作,因为sprintf 替换了该令牌;同样,$format 不应包含“$1”,否则您可能会得到奇怪的结果。
    猜你喜欢
    • 2013-06-29
    • 2011-12-20
    • 2012-06-03
    • 1970-01-01
    • 2013-09-15
    • 2012-08-04
    • 1970-01-01
    • 2017-12-04
    相关资源
    最近更新 更多