【问题标题】:Preg Replace - replace second occurance of a matchPreg_replace - 替换第二个匹配项
【发布时间】:2011-04-16 14:56:29
【问题描述】:

我对php比较陌生,希望有人可以帮助我替换正则表达式,或者我不确定的匹配替换。

我想自动加粗(匹配的第二次出现),然后将匹配的第 4 次出现斜体,然后将匹配的第 7 次出现下划线。

这基本上是为了内容的 SEO 目的。

我已经做了一些替换:并且认为这应该可以解决问题?

preg_replace( pattern, replacement, subject [, limit ])

我已经知道我想在中使用的词

'pattern' is also a word that is already defined like [word].
`replacement` 'This is a variable I am getting from a mysql db.
'subject' - The subject is text from a db.

假设我有这个内容:这或多或少地解释了我想要做什么。

这是我要替换的文本示例。在本文中,我想让 example example 这个词第 4 次以斜体显示。然后我想跳过文本中出现的第 5 次单词 example,以及第 6 次,最后想让 example 第 7 次出现在文本中为它加下划线。在此示例中,我使用超链接作为下划线示例,因为我在文本编辑器中看不到下划线功能。 example这个词在文中可能出现的次数更多,但我唯一的要求是下划线一次,加粗一次,斜体一次。我以后可能会决定对“示例”这个词做一些引用,但这还不是优先事项。

如果单词的出现次数不超过 7 次,代码不要出现错误也很重要。

我将如何做到这一点,任何想法将不胜感激。

【问题讨论】:

    标签: php preg-replace preg-match


    【解决方案1】:

    您可以使用preg_split 在匹配处拆分文本,应用修改,然后将所有内容重新组合在一起:

    $parts = preg_split('/(example)/', $str, 7, PREG_SPLIT_DELIM_CAPTURE);
    if (isset($parts[3])) $parts[3] = '<b>'.$parts[3].'</b>';
    if (isset($parts[7])) $parts[7] = '<i>'.$parts[7].'</i>';
    if (isset($parts[13])) $parts[13] = '<u>'.$parts[13].'</u>';
    $str = implode('', $parts);
    

    第 i 个匹配的索引公式为 index = i · 2 - 1.

    【讨论】:

    • 谢谢秋葵!我几乎可以开始将我所有的问题直接发送给您 :-) 大多数时候,您的答案是有效的!谢谢一百万。
    • 嗨,Gumbo 现在我完全糊涂了。我已经使用了此页面上的代码24hour-casino-games.com/casino-reviews/online/… h1 不是字符串的一部分。所以如果我算上“五月花赌场”的话。 5 月 2 日花赌场被突出显示,这是正确的。然后第四次使用它是斜体 - 这是正确的。然后如果我在 $str, 7 (14) 之后创建值,它会在位置 7 处显示另一个粗体,这是正确的。你能解释一下为什么 $parts[7] 显示在位置 4 和 $parts[13] 显示在位置 7...谢谢
    • @Gerald Ferreira:当preg_split 捕获分隔符(模式的匹配项)时,结果始终是奇数个部分,其中每个偶数部分都有一个奇数索引(从零开始)是一个分隔符。所以第一个分隔符在 1,第二个在 3,第三个在 5,依此类推。这可以用 i · 2 - 1 表示。
    • 好的 - 现在感谢 Gumbo。我现在将数字增加了 1 - 然后它选择了 May Flower 和 May Flower 之间的所有文本,如果我再次输入奇数,它会选择这个词! - 非常感谢您的帮助 - 这是一个很好的解决方案! - 我看到下划线已被贬值,所以我将使用链接而不是......
    【解决方案2】:

    正则表达式本身不能计数,preg_ 函数提供的帮助很小。你需要一个解决方法。如果您实际上只搜索一个单词,您可能想要使用字符串函数。否则尝试:

    // just counting
    if (7 >= preg_match_all($pattern, $subject, $matches)) {
    
       $cb_num = 0;
       $subject = preg_replace_callback($pattern, "cb_ibu", $subject);
    }
    
    function cb_ibu($match) {
        global $cb_num;
    
        $match = $match[0];
    
        switch (++$cb_num) {
            case 2: return "<b>$match</b>";
            case 4: return "<i>$match</i>";
            case 7: return "<u>$match</u>";
            default: return $match;
        }
    }
    

    诀窍是有一个做账的回调。在那里添加任何规则都很容易。

    【讨论】:

    • 谢谢马里奥,我现在正在检查这个......只是为了确保
    • $pattern = '/[word]/' $subject = ?, $matches = ?我不知道该在主题和匹配项中添加什么...
    • $matches 只是一个未使用的一次性变量。但是$subject 是您的源文本。
    • 我是这样实现的... $pattern = '/'.$g_page_identify.'/'; $主题 = $g_page_content2; // 只计算 if (7 >= preg_match_all($pattern, $subject, $matches)) { $cb_num = 0; $subject = preg_replace_callback($pattern, "cb_ibu", $subject); } 函数 cb_ibu($match) { 全局 $cb_num; $match = $match[0]; switch (++$cb_num) { case 2: return "$match";案例4:返回“$match”;案例 7:返回“$match”;默认值:返回 $match; } }
    • 感谢mario的反馈,我很感激,我最终选择了Gumbo提供的解决方案
    【解决方案3】:

    这是一个有趣的问题。我的实现是:

    function replace_exact($word, $tag, $string, $limit) {
        $tag1 = '<'.$tag.'>';
        $tag2 = '</'.$tag.'>';
        $string = str_replace($word, $tag1.$word.$tag2, $string, 1);
        if ($limit==1) return $string;
        return str_replace($tag1.$word.$tag2,$word,$string,$limit-1);
    }
    

    像这样使用它:

    echo replace_exact('Example', 'b', $source_text, 2);
    echo replace_exact('Example', 'i', $source_text, 4);
    

    我不知道它的工作速度有多快,但它会比 preg_replace 快。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-10-07
      • 1970-01-01
      • 2013-10-28
      • 1970-01-01
      • 1970-01-01
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多