您当前的位置是:首页-SEO宝典

文章正文关键字添加链接,互相包含的关键字,只能替换短的关键字的链接

【发表于】:2010/11/30 9:31:00  已被访问:228次
前提:
如果没有使用过文章正文的“关键字替换链接功能”,请跳过本文,先弄清楚那个功能的用途再阅读本文。

问题的提出:
举例假定一篇文章,设置了两个关键字: “美国”、“美国股市”
文章正文里假定出现这样的文字“美国今年经济不好,美国股市累计下挫50%……”。
那么生成后的替换结果,就变成了“美国今年经济不好,美国股市累计下挫下挫50%……”。
也就是说,当存在互相包含的关键字的时候,最后替换的结果,就是长关键字无法替换出来,都以短关键字为准了

假定你就是需要长短关键字都能替换,那就必须改动DEDE的代码了!

楼下的很急,我就继续写啦……


以下这一段,是修改思路,如果不是编程者或者爱好者,请跳过~~~~
我查看了代码,首先找到替换关键字链接是在include/arc.archives.class.php 这个文件的function ReplaceKeyword里编写的代码。
原编码如下(不同版本有细微差别,这里以5.5 GBK的为例):
复制代码 
function ReplaceKeyword($kw,&$body) 
    { 
        global $cfg_cmspath; 
        $maxkey = 5; 
        $kws = explode(",",trim($kw));    //以分好为间隔符 
        $i=0; 
        $karr = $kaarr = $GLOBALS[’replaced’] = array(); 

        //暂时屏蔽超链接 
        $body = preg_replace("/(<a(.*))(>)(.*)(<)(\/a>)/isU", ’\\1-]-\\4-[-\\6’, $body); 

        foreach($kws as $k) 
        { 
            $k = trim($k); 
            if($k!="") 
            { 
                if($i > $maxkey) 
                { 
                    break; 
                } 
                $myrow = $this->dsql->GetOne("Select * from #@__keywords where keyword=’$k’ And rpurl<>’’ "); 
                if(is_array($myrow)) 
                { 
                    $karr[] = $k; 
                    $GLOBALS[’replaced’][$k] = 0; 
                    $kaarr[] = "<a href=’{$myrow[’rpurl’]}’><u>$k</u></a>"; 
                } 
                $i++; 
            } 
        } 
        $body = preg_replace("/(^|>)([^<]+)(?=<|$)/sUe", "_highlight(’\\2’, \$karr, \$kaarr, ’\\1’)", $body); 

        //恢复超链接 
        $body = preg_replace("/(<a(.*))-\]-(.*)-\[-(\/a>)/isU", ’\\1>\\3<\\4’, $body); 
        return $body; 
    }



上面的代码,简单说就是这个过程:
1、分解关键字列表为数组
2、暂时屏蔽BODY里超链接(把超链接及链接文字另外改成一个特殊的格式)
3、遍历关键字数组里的每个关键字,从关键字总表里查找其对应的链接地址,形成关键字链接数组
4、把关键字数组和关键字链接数组,都作为参数,传到_highlight函数里对BODY进行关键字替换链接
5、恢复BODY里超链接

这个过程,当遇到上述例子的互相包含的关键字的时候,就会出现问题,因为屏蔽超链接和恢复超链接的过程在头尾,而中间替换关键字的过程里没有每次都屏蔽超链接。
例如“美国今年经济不好,美国股市累计下挫50%……”在替换链接的过程里
先根据“美国股市”被替换成“美国今年经济不好,美国股市累计下挫50%……”
然后遇到“美国”,再次被替换成“美国今年经济不好,美国股市累计下挫下挫50%……”。
…………………………

解决的思路就是:按关键字长短排列,把长的关键字排在前面。然后每次按一个关键字替换连接,替换前后都进行屏蔽超链接和恢复超链接的过程,这样就能避免被包含的关键字在后面重复替换前面替换过的关键字。



以上文字,主要是给学习PHP和DEDE的人做参考的,主要是思路的学习,毕竟授人以渔才是最高境界。
如果想直接用,可以看以下文字(适用于dede5.5 GBK,其他版本的请自行参考一下代码修改,不要来问我,鱼已经摆在面前了,动动筷子自己吃就是了,不能叫别人喂你)
【解决方案】 复制代码 
function ReplaceKeyword($kw,&$body) 
    { 
        global $cfg_cmspath; 
        $maxkey = 5; 
        $kws = explode(",",trim($kw));    //以分好为间隔符 
        //* 按长度排序关键字数组 
        $kws2=array();                                 //新增 BY NIC 
        $kws_len=count($kws);    //新增 BY NIC 
        for($i=0;$i<$kws_len;$i++){              //新增 BY NIC 
                 $max=0; $max_pos=-1;            //新增 BY NIC 
                 for($j=0;$j<$kws_len;$j++){     //新增 BY NIC 
                       $strlen = strlen($kws[$j]);   //新增 BY NIC 
                       if ($max<=$strlen) {$max=$strlen;$max_pos=$j;}    //新增 BY NIC 
                 }                                //新增 BY NIC   
                $kws2[]=$kws[$max_pos]; $kws[$max_pos]="";           //新增 BY NIC 
        }  //新增 BY NIC 
        //* 按长度排序关键字数组 
        $i=0; 
        $karr = $kaarr = $GLOBALS[’replaced’] = array(); 
        $karr[] = "";  //新增 BY NIC 
        $kaarr[] ="";  //新增 BY NIC 

        //暂时屏蔽超链接 
        //$body = preg_replace("/(<a(.*))(>)(.*)(<)(\/a>)/isU", ’\\1-]-\\4-[-\\6’, $body);   //屏蔽 BY NIC 
        foreach($kws2 as $k) 
        { 
            $k = trim($k); 
            if($k!="") 
            { 
                if($i > $maxkey) 
                { 
                    break; 
                } 
                $myrow = $this->dsql->GetOne("Select * from #@__keywords where keyword=’$k’ And rpurl<>’’ "); 
                if(is_array($myrow)) 
                { 
                    $karr[0] = $k;                                                            //修改 BY NIC 
                    $GLOBALS[’replaced’][$k] = 0; 
                    $kaarr[0] = "<a href=’{$myrow[’rpurl’]}’>$k</a>"; //修改 BY NIC 
                     
                    $body = preg_replace("/(<a(.*))(>)(.*)(<)(\/a>)/isU", ’\\1-]-\\4-[-\\6’, $body);   //新增 BY NIC           
                    $body = preg_replace("/(^|>)([^<]+)(?=<|$)/sUe", "_highlight(’\\2’, \$karr, \$kaarr, ’\\1’)", $body);  //新增 BY NIC                 
                     $body = preg_replace("/(<a(.*))-\]-(.*)-\[-(\/a>)/isU", ’\\1>\\3<\\4’, $body);       //新增 BY NIC 
                } 
                $i++; 
            } 
        } 
        //$body = preg_replace("/(^|>)([^<]+)(?=<|$)/sUe", "_highlight(’\\2’, \$karr, \$kaarr, ’\\1’)", $body);   //屏蔽 BY NIC 

        //恢复超链接 
        //$body = preg_replace("/(<a(.*))-\]-(.*)-\[-(\/a>)/isU", ’\\1>\\3<\\4’, $body);  //屏蔽 BY NIC 
        return $body; 
    } 





这个方法,其实就是按照DEDE本身的基本思路,把算法结构稍做了调整。效率其实并不高,如果是熟悉正则表达式的朋友,其实可以尝试不这样进行修改,而是调整_highlight函数里的这一句:
    $string = preg_replace("/".preg_quote($word)."/", $result[$key], $string, $cfg_replace_num);
让它可以避免替换到包含在<a></a>中的文字即可~~~
 
上下篇: 防止关键字重复替换 各大搜索引擎网站提交登录入口,网站登录入口大全

最新推荐信息