在没有超链接的情况下替换文本为超链接

6
一个更好的例子是这样的:
$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>"

你希望如何替换你找到的单词?用“鱿鱼”代替“狗”,用“鸟”代替“猫”吗?如果是这样,那么“猴子”应该被替换成什么?或者逐步用新的动物替换,直到所有动物都被使用且不重复?请澄清。 - Josh
啊,那我建议使用 preg_replace 并迭代每个 $remove。负向先行断言应该可以解决问题。 - Josh
1个回答

4

编辑:

我花了很长时间,但以下是我的成果:

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,福特野马),array(42,福特),(324,本田));echo preg_replace($remove, "<a href='?carID=".$replaceWith[0][0]."'>".$replaceWith[0][1]."</a>",$string); 需要提高效率的原因是因为将会有数千个品牌和型号。我知道需要在其中进行查找 - 可能需要使用 preg_match 或类似的东西来进行循环。 - Chris
哇!!!这真是一些疯狂的东西,像梦一样工作。非常感谢您抽出时间为我解决问题!!!最后一个问题,比较时是否可以忽略大小写?“那是一辆非常漂亮的福特野马,如果每辆福特都像这辆本田一样漂亮就好了,但如果你有一辆福特野马或经典迷你车,你会非常开心!”否则它只会比较大小写。再次感谢。 - Chris
如果你使用:"$replaceWith = array('Ford Mustang'=>123,'Ford'=>42,'Honda'=>324);" 似乎只有在字符串的大小写与数组的大小写不匹配时才会发生。超链接为空:S - Chris
@chris,好的,已经添加了一个负向回顾,用于等号符号。 - mowwwalker
非常感谢!!!我不知道如何给你发消息,也不确定你是否会看到这条信息。但是非常感谢! - Chris
@chris,是的,当你在他们的帖子上发表评论或使用@符号标记他们时,它会通知他们。祝编码愉快! - mowwwalker

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接