douhuike3199 2012-01-25 16:56
浏览 39
已采纳

将文本替换为尚未存在的超链接

A better example would be this:

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

I want to replace the car names with a link for manufacturer and model if they match, or just manufacturer, but if there is a make and model it puts links within links if you use str replace for example....

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

This gives the result:

"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>"

I only want it to create a hyperlink if there isn't one already like this:

  "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>"
  • 写回答

1条回答 默认 最新

  • dongzhou1865 2012-01-25 19:41
    关注

    edit:

    Took me a good while, but here's what I came up with:

    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);
    
    }
    

    Pass it an array such as the one you were talking about:

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

    and a string:

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

    It gives precedence to larger string keys, so if you have ford and ford mustang, it will replace ford mustang with the link.




    Not very practical, but might work.

    $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);
    

    I used regular expressions with negative lookaheads and lookbehinds to make sure the portion of the string we're replacing isn't part of an alphanumeric sequence (like 12ford23 or afford) or touching the start or end tag of an element.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 BP神经网络控制倒立摆
  • ¥20 要这个数学建模编程的代码 并且能完整允许出来结果 完整的过程和数据的结果
  • ¥15 html5+css和javascript有人可以帮吗?图片要怎么插入代码里面啊
  • ¥30 Unity接入微信SDK 无法开启摄像头
  • ¥20 有偿 写代码 要用特定的软件anaconda 里的jvpyter 用python3写
  • ¥20 cad图纸,chx-3六轴码垛机器人
  • ¥15 移动摄像头专网需要解vlan
  • ¥20 access多表提取相同字段数据并合并
  • ¥20 基于MSP430f5529的MPU6050驱动,求出欧拉角
  • ¥20 Java-Oj-桌布的计算