求这样的一个替换算法。 本帖最后由 lovewangya 于 2009-10-26 10:39:37 编辑 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日,吕正操曾经是张学良的一名副将军引用想实现替换之后如下:<a href=http://xxx.com?p=张学良将军> 张学良将军 </a>是我十分敬重的一位将军, <a href=http://xxx.com?p=张学良>张学良 </a>生于xxx年xx月xx日,吕正操曾经是张学良的一名副 <a href=http://xxx.com?p=将军>将军 </a>,你的'张学良' 替换的是第一个,'将军'却替换第二个,没搞错吧? 没有搞错我的意思是说:如果文章当中有:<a href=http://xxx.com?p=张学良将军> 张学良将军 </a>这个链接那么关键字:张学良,将军 就不要再去动这个链接里面的内容了。 或许有代码更清晰。这样?$str = '张学良将军张学良将军张学良将军xx张学良xx将军xx张学良xx将军';$str = preg_replace('/张学良将军|张学良(?!将军)|(?<!张学良)将军/e','fxx("$0")',$str);function fxx($s){ static $o = array(); if(!$o[$s]) { $o[$s] = true; return "<a href='#'>".$s."</a>"; } return $s;}echo $str; $str = '张学良将军张学良将军张学良将军xx张学良xx将军xx张学良xx将军';$str = preg_replace('/张学良将军|张学良(?!将军)|(?<!张学良)将军/e','fxx("$0")',$str);function fxx($s){static $o = array();if(!$o[$s]){$o[$s] = true;return " <a href='#'>".$s." </a>";}return $s;}echo $str; 谢谢您的关注,其实一般的cms都是选择第一次出现的关键字替换一次就可以了,我的也是,可能是比较着急,选择了第二个将军,应当是第一个将军才对,抱歉。让您误解了. 最简单的方法是先提取a标签的内容,然后用个临时的id放在那,然后替换,最后再把临时id替换为a标签,href属性里的中文可以编一下码~~ $str = preg_replace('/张学良将军|张学良(?!将军)|(?<!张学良)将军/e','fxx("$0")',$str);/e 和$0是什么意思 谢谢各位的提醒,大家给了我思路,我也把自己的成果和大家分享一下,大家看有什么错误和不正常的情况没有:str_replace_once函数为只替换一次的自己定义的函数,函数原形没有给出,$str = array();$str[0]["keyword"] = "张学良";$str[0]["url"] = "http://xxx.com";$str[1]["keyword"] = "将军";$str[1]["url"] = "http://xxx.com";$str[2]["keyword"] = "张学良将军";$str[2]["url"] = "http://xxx.com";$str[3]["keyword"] = "军";$str[3]["url"] = "http://xxx.com";function usort_strlen_desc($a, $b)//按照字符串长度降序排列{ $lena = strlen($a["keyword"]); $lenb = strlen($b["keyword"]); return $lena > $lenb ? -1 : ($lena == $lenb ? 0 : 1);}$str2 = "张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日,吕正操曾经是张学良的一名副将军";keywordAddUrl($str2,$str);function keywordAddUrl($str,$keywords){ usort($keywords,"usort_strlen_desc"); for($i=0;$i<count($keywords);$i++) { $str = str_replace_once($keywords[$i]["keyword"],"~_{$i}_~",$str); } echo $str; echo "<hr>"; for($i=0;$i<count($keywords);$i++) { $str = str_replace_once("~_{$i}_~","<a href=\"" . $keywords[$i]["url"] ."\" target=\"_blank\">" . $keywords[$i]["keyword"] . "</a>",$str); } echo $str;} 你那个貌似有点复杂,刚刚想到了想两个很古怪的算法,有一个算法比较复杂,利用关键字拆分成一颗树,具体就不说了,下面这个比较好理解$str2 = "张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日,吕正操曾经是张学良的一名副将军";$search = array("张学良","将军","张学良将军","军");$replace = array("<a href=\"dasdasdasd?=张学良\">张学良</a>","<a href=\"dasdasdasd?=将军\">将军</a>","<a href=\"dasdasdasd?=将军\">张学良将军</a>","<a href=\"dasdasdasd?=将军\">军</a>");print_r(my_replace($search,$replace,$str2));function my_replace($search,$replace,$content){ $mixKey = "cay"; foreach($search as &$one){ $one = "/".$one."/"; } foreach($replace as &$one){ $temp = $one[0]; for($i=1;$i<strlen($one);$i++) $temp .= $mixKey.$one[$i]; $one = $temp; } $content = preg_replace($search,$replace,$content); return str_replace($mixKey ,'',$content);}preg_replace对结果还可以用函数再处理,可以变得更动态化 这样写$s = <<< TEXT张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日, 吕正操曾经是张学良的一名副将军 TEXT;//关键字表$dict = array('张学良', '张学良将军', '将军');//按长度优先规格化关键字表foreach($dict as $v) $ind[] = strlen($v);array_multisort($ind, SORT_DESC , $dict);//print_r($dict);//Array ( [0] => 张学良将军 [1] => 张学良 [2] => 将军 )//构造规则串foreach($dict as $v) $pattern[] = "/(^|.)($v)(.|$)/";//print_r($pattern);//定义preg_replace_callback回调函数function callback($r) { if($r[1] == '=' || $r[1] == '>' || $r[3] == '>' || $r[3] == '<') return $r[0]; return "$r[1]<a href=http://xxx.com?p=$r[2]>$r[2]</a>$r[3]";}echo preg_replace_callback($pattern, 'callback', $s);<a href=http://xxx.com?p=张学良将军>张学良将军</a>是我十分敬重的一位<a href=http://xxx.com?p=将军>将军</a>,<a href=http://xxx.com?p=张学良>张学良</a>生于xxx年xx月xx日, 吕正操曾经是<a href=http://xxx.com?p=张学良>张学良</a>的一名副<a href=http://xxx.com?p=将军>将军</a> 这个结果不符合楼主的要求<a href="dasdasdasd?=张学良">张学良</a><a href="dasdasdasd?=将军">将军</a>是我十分敬重的一位<a href="dasdasdasd?=将军">将军</a>,<a href="dasdasdasd?=张学良">张学良</a>生于xxx年xx月xx日,吕正操曾经是<a href="dasdasdasd?=张学良">张学良</a>的一名副<a href="dasdasdasd?=将军">将军</a> 请教合适的算法。 如何算出某周的第一天和最後一天 mysql_connect問題 pdo插入表数据为什么插入不了呢,也不报错。 这种情况下我该如何生成网页? 关于给图片加水印 php mysql mysql_fetch_array()报错问题,刷新就没事了。 菜鸟问题! 紧急问题:对形成的表格进行按行删除及修改 急!如何避免刷新导致FORM提交的数据重复处理?? php 调用js函数 遇转义问题,请教 请问如何从radio button取值,存储到mysql数据库??
吕正操曾经是张学良的一名副将军引用
想实现替换之后如下:
<a href=http://xxx.com?p=张学良将军> 张学良将军 </a>是我十分敬重的一位将军, <a href=http://xxx.com?p=张学良>张学良 </a>生于xxx年xx月xx日,吕正操曾经是张学良的一名副 <a href=http://xxx.com?p=将军>将军 </a>,
你的'张学良' 替换的是第一个,'将军'却替换第二个,没搞错吧?
这个链接那么关键字:张学良,将军
就不要再去动这个链接里面的内容了。
static $o = array();
if(!$o[$s])
{
$o[$s] = true;
return "<a href='#'>".$s."</a>";
}
return $s;
}
echo $str;
static $o = array();
if(!$o[$s])
{
$o[$s] = true;
return " <a href='#'>".$s." </a>";
}
return $s;
}
echo $str;
str_replace_once函数为只替换一次的自己定义的函数,函数原形没有给出,$str = array();
$str[0]["keyword"] = "张学良";
$str[0]["url"] = "http://xxx.com";
$str[1]["keyword"] = "将军";
$str[1]["url"] = "http://xxx.com";
$str[2]["keyword"] = "张学良将军";
$str[2]["url"] = "http://xxx.com";
$str[3]["keyword"] = "军";
$str[3]["url"] = "http://xxx.com";function usort_strlen_desc($a, $b)//按照字符串长度降序排列
{
$lena = strlen($a["keyword"]);
$lenb = strlen($b["keyword"]);
return $lena > $lenb ? -1 : ($lena == $lenb ? 0 : 1);
}
$str2 = "张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日,吕正操曾经是张学良的一名副将军";
keywordAddUrl($str2,$str);
function keywordAddUrl($str,$keywords)
{
usort($keywords,"usort_strlen_desc");
for($i=0;$i<count($keywords);$i++)
{
$str = str_replace_once($keywords[$i]["keyword"],"~_{$i}_~",$str);
}
echo $str;
echo "<hr>";
for($i=0;$i<count($keywords);$i++)
{
$str = str_replace_once("~_{$i}_~","<a href=\"" . $keywords[$i]["url"] ."\" target=\"_blank\">" . $keywords[$i]["keyword"] . "</a>",$str);
}
echo $str;
}
$search = array("张学良","将军","张学良将军","军");
$replace = array("<a href=\"dasdasdasd?=张学良\">张学良</a>","<a href=\"dasdasdasd?=将军\">将军</a>","<a href=\"dasdasdasd?=将军\">张学良将军</a>","<a href=\"dasdasdasd?=将军\">军</a>");print_r(my_replace($search,$replace,$str2));function my_replace($search,$replace,$content){
$mixKey = "cay";
foreach($search as &$one){
$one = "/".$one."/";
}
foreach($replace as &$one){
$temp = $one[0];
for($i=1;$i<strlen($one);$i++)
$temp .= $mixKey.$one[$i];
$one = $temp;
}
$content = preg_replace($search,$replace,$content);
return str_replace($mixKey ,'',$content);
}
preg_replace对结果还可以用函数再处理,可以变得更动态化
张学良将军是我十分敬重的一位将军,张学良生于xxx年xx月xx日,
吕正操曾经是张学良的一名副将军
TEXT;//关键字表
$dict = array('张学良', '张学良将军', '将军');//按长度优先规格化关键字表
foreach($dict as $v) $ind[] = strlen($v);
array_multisort($ind, SORT_DESC , $dict);
//print_r($dict);//Array ( [0] => 张学良将军 [1] => 张学良 [2] => 将军 )//构造规则串
foreach($dict as $v) $pattern[] = "/(^|.)($v)(.|$)/";
//print_r($pattern);//定义preg_replace_callback回调函数
function callback($r) {
if($r[1] == '=' || $r[1] == '>' || $r[3] == '>' || $r[3] == '<') return $r[0];
return "$r[1]<a href=http://xxx.com?p=$r[2]>$r[2]</a>$r[3]";
}echo preg_replace_callback($pattern, 'callback', $s);
<a href=http://xxx.com?p=张学良将军>张学良将军</a>是我十分敬重的一位<a href=http://xxx.com?p=将军>将军</a>,<a href=http://xxx.com?p=张学良>张学良</a>生于xxx年xx月xx日,
吕正操曾经是<a href=http://xxx.com?p=张学良>张学良</a>的一名副<a href=http://xxx.com?p=将军>将军</a>
<a href="dasdasdasd?=张学良">张学良</a><a href="dasdasdasd?=将军">将军</a>是我十分敬重的一位<a href="dasdasdasd?=将军">将军</a>,<a href="dasdasdasd?=张学良">张学良</a>生于xxx年xx月xx日,吕正操曾经是<a href="dasdasdasd?=张学良">张学良</a>的一名副<a href="dasdasdasd?=将军">将军</a>