【问题标题】:String Replace that contains hashtags-php包含 hashtags-php 的字符串替换
【发布时间】:2021-11-09 15:30:46
【问题描述】:

我有一个这样的字符串

$content="#Love #Lovestories #Lovewalapyar";

想让这些主题标签可点击。

我有一个数组。

$tags=
(
    [0] => stdClass Object
        (
            [TOPIC_ID] => 132
            [TOPIC_NAME] => Love
            [TOPIC_URL] => http://local/topic/132/love            
        )

    [1] => stdClass Object
        (
            [TOPIC_ID] => 3347
            [TOPIC_NAME] => LoveStories
            [TOPIC_URL] => http://local/topic/3347/lovestories            
        )

  
    [2] => stdClass Object
        (
            [TOPIC_ID] => 43447
            [TOPIC_NAME] => lovewalapyar
            [TOPIC_URL] => http://local/topic/43447/lovewalapyar            
        )

);

Using this to make hashtags clickable.

foreach($tags as $tag){
    $content=str_ireplace('#'.$tag->TOPIC_NAME, '<a href="'.$tag->TOPIC_URL.'" title="'.htmlentities($tag->TOPIC_NAME).'">#'.$tag->TOPIC_NAME.'</a>', $content);
}

得到这个: 它只替换 love 而不是其他字符串。

尝试替换/使这些主题标签可点击。

任何帮助将不胜感激。

【问题讨论】:

    标签: php string replace str-replace


    【解决方案1】:

    我会使用正则表达式 /#(\w*)/(井号标签和空格)和 preg_replace() 来替换所有匹配项。

    类似这样的:

    $content = "#Love #Lovestories #Lovewalapyar";
    $pattern = '/#(\w*)/';
    $replacement = '<a href="#$1">$1</a>';
    preg_replace($pattern, $replacement, $content);
    

    这会给你:

    <a href="#Love">Love</a> 
    <a href="#Lovestories">Lovestories</a> 
    <a href="#Lovewalapyar">Lovewalapyar</a>
    

    你可以测试一下regex online here


    如果您需要一些高级逻辑,如 cmets 中提到的 Magnus Eriksson,您可以使用 preg_match_all 并遍历找到的匹配项。

    类似这样的:

    $content = "#Love #Lovestories #Lovewalapyar";
    $pattern = '/#(\w*)/';
    preg_match_all($pattern, $content, $matches);
    foreach ($matches[1] as $key => $match) {
        // do whatever you need here, you might want to use $tag = $tags[$key];
    }
    

    【讨论】:

    • 但这并不是那么简单,因为他们想要替换它们的 URL 是特定于每个标签的(包括不同的 id),而不仅仅是href="#tagname"。这并没有给他们想要的结果。
    • 感谢您的尝试。
    【解决方案2】:

    原因很简单。您的主题标签是其他主题标签的子字符串。 为了避免这种重叠问题,您可以以非递增方式对数组进行排序,先替换较长的字符串,然后替换较短的字符串,完全避免重叠问题,如下所示:

    <?php
    
    usort($tags,function($a,$b){
       return strlen($b->TOPIC_NAME) <=> strlen($a->TOPIC_NAME);
    });
    

    更新:

    &lt;a&gt;&lt;/a&gt; 中的标签文本导致str_ireplace 重新考虑它。为此,您需要在数组中传递数组值及其各自的替换,或者,您可以使用 HTML 字符实体 &amp;#35;,而不是添加 &amp;#35;,它将被 str_ireplace() 忽略并且可以正常工作,如下:

    '<a ...>&#35;'.$tag->TOPIC_NAME.'</a>';
    

    更新片段:

    <?php
    
    usort($tags,function($a,$b){
       return strlen($b->TOPIC_NAME) <=> strlen($a->TOPIC_NAME);
    });
    
    foreach($tags as $tag){
        $content = str_ireplace('#'.$tag->TOPIC_NAME, '<a href="'.$tag->TOPIC_URL.'" title="'.htmlentities($tag->TOPIC_NAME).'">&#35;'. $tag->TOPIC_NAME.'</a>', $content);
    }
    

    【讨论】:

    • 亲爱的@nice_dev,我尝试了多种逻辑。但它工作得很好。非常感谢。
    • @SurajAnand 很高兴它运行良好。如果您不介意,您可以将其标记为已接受吗?这样,未来的研究人员就会知道这是一个可行的解决方案。
    • 当然,@nice_dev
    猜你喜欢
    • 2016-06-13
    • 1970-01-01
    • 2021-06-08
    • 2011-03-10
    • 2019-05-25
    • 1970-01-01
    • 2014-03-30
    • 2022-01-22
    相关资源
    最近更新 更多