【问题标题】:Replace text with hyperlinks where there isn't already one用还没有超链接的文本替换文本
【发布时间】:2012-02-18 20:52:13
【问题描述】:

一个更好的例子是:

$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda";

我想用制造商和型号的链接替换汽车名称,如果它们匹配,或者只是制造商,但如果有品牌和型号,如果你使用 str replace 例如,它会将链接放在链接中......

$remove = array("ford mustang","ford","honda");
$replaceWith = array("<a href='fordID'>ford</a>","<a href='fordmustangID'>ford mustang</a>","<a href='hondaID'>honda</a>");

这给出了结果:

"That is a very nice <a href='<a href='fordmustangID'>ford mustang</a>ID'><a href='fordmustangID'>ford mustang</a></a>, if only every other <a href='fordmustangID'>ford mustang</a> was quite as nice as this <a href='hondaID'>honda</a>"

如果还没有这样的超链接,我只希望它创建一个超链接:

  "That is a very nice <a href='fordmustangID'>ford mustang</a>, if only every other <a href='fordID'>ford</a> was quite as nice as this <a href='hondaID'>honda</a>"

【问题讨论】:

  • 您希望找到的单词如何被替换? “狗”和“鱿鱼”,“猫”和“鸟”?如果是这样,“猴子”用什么代替?或者,逐步更换新动物,直到所有动物都用完而不再重复?请澄清一下。
  • 啊,那么我建议使用preg_replace 并遍历每个$remove。负前瞻应该做到这一点。

标签: php regex preg-replace str-replace


【解决方案1】:

编辑:

花了我一段时间,但这是我想出的:

function replaceLinks($replacements, $string){
    foreach($replacements as $key=>$val){
        $key=strtolower((string)$key);
        $newReplacements[$key]=array();
        $newReplacements[$key]['id']=$val;
        //strings to make sure the search isn't in front of
        $newReplacements[$key]['behinds']=array();
        //strings to make sure the search isn't behind
        $newReplacements[$key]['aheads']=array();
        //check for other searches this is a substring of
        foreach($replacements as $key2=>$val2){
            $key2=(string)$key2;
            /* 
            //debugging
            $b = ($key=='11 22'&&$key2=='11 22 33');
            if($b){
                l('strlen $key2: '.strlen($key2));
                l('strlen $key: '.strlen($key));
                l('strpos: '.(strpos($key2,$key)));

            }
            */
            //the second search is longer and the first is a substring of it
            if(strlen($key2)>strlen($key) && ($pos=strpos($key2,$key))!==false){
                //the first search isn't at the start of the second search ('the ford' and 'ford')
                if($pos!=0){
                    $newReplacements[$key]['behinds'][]=substr($key2,0,$pos);
                }
                //it's not at the end ('ford' and 'fords')
                if(($end=$pos+strlen($key))!=strlen($key2)){
                    $newReplacements[$key]['aheads'][]=substr($key2,$end);
                }
            }
        }
    }
    foreach($newReplacements as $key=>$item){
        //negative lookbehind for words or >
        $tmp="/(?<![\w>=])";
        //negative lookbehinds for the beginnings of other searches that this search is a subtring of
        foreach($item['behinds'] as $b){
            $tmp.="(?<!$b)";
        }
        //the actual search
        $tmp.="($key)";
        //negative lookaheads for ends of other searches that this is a substring of.
        foreach($item['aheads'] as $a){
            $tmp.="(?!$a)";
        }
        //case insensitive
        $tmp.='/ie';
        $replacementMatches[]=$tmp;
    }
    return preg_replace($replacementMatches,'"<a href=\"".$newReplacements[strtolower("$1")]["id"]."\">$1</a>"' ,$string);

}

向它传递一个数组,例如您所说的那个:

$replaceWith = array('ford mustang'=>123,'ford'=>42,'honda'=>324);

还有一个字符串:

$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda";

echo replaceLinks($replaceWith,$string);

它优先于较大的字符串键,因此如果您有fordford mustang,它将用链接替换ford mustang




不是很实用,但可能有用。

$string = "That is a very nice ford mustang, if only every other ford was quite as nice as this honda";
$remove = array("/(?<![\w>])ford mustang(?![\w<])/",'/(?<![>\w])ford(?! mustang)(?![<\w])/',"/(?<![>\w])honda(?![<\w])/");
$replaceWith = array("<a href='fordmustangID'>ford mustang</a>","<a href='fordID'>ford</a>","<a href='hondaID'>honda</a>");
echo preg_replace($remove, $replaceWith,$string);

我使用带有负前瞻和后视的正则表达式来确保我们要替换的字符串部分不是字母数字序列的一部分(如12ford23afford)或触摸的开始或结束标记一个元素。

【讨论】:

  • 这几乎正是我的目标。是否有可能通过说...来提高效率... //////// 我知道下面的两行代码是不准确的,这只是为了说明我的意思 $replaceWith = array(array(123 ,福特野马),阵列(42,福特),(324,本田)); echo preg_replace($remove, "".$replaceWith[0][1]."",$string) ;需要效率的原因是因为将有数千种品牌和型号。我知道那里需要看一下 - 可能是预赛或类似的东西来制作循环。
  • 哇!!!!那是一些疯狂的东西,就像做梦一样。非常感谢您花时间为我解决这个问题!!!!最后也是最后一个问题,是否可以在比较时使其不区分大小写? “这是一辆非常不错的福特野马,如果其他所有福特都和这辆本田一样好就好了,但如果你有一辆福特野马或经典迷你,你会是一个非常幸福的人!”否则它只比较小写或大写。再次感谢您
  • 如果你使用:"$replaceWith = array('Ford Mustang'=>123,'Ford'=>42,'Honda'=>324);"似乎仅在字符串的大小写与数组的大小写不匹配时才会发生超链接为空:S
  • @chris,好的,为等号添加了一个否定的后视。
  • 非常感谢!!!!!!!我不知道如何给你发消息,也不确定你是否会找到这个。不过非常感谢!
猜你喜欢
  • 2018-03-22
  • 1970-01-01
  • 2017-10-15
  • 1970-01-01
  • 1970-01-01
  • 2023-01-25
  • 1970-01-01
  • 2013-09-13
相关资源
最近更新 更多