问题是这样的,我在做一个blog系统,一般的blog系统发表日记后可以选择在首页显示日记的全部内容,也可以选择显示300个字(51就是这样),也可以选择不显示。
如果用户选择的是在首页显示300个字的话就有可能出现这样一个问题:
如果文章的内容是这样的 “……文字文字文<p>字文字文字文字文字<img src=sss.jpg><br />……” ,第300个字符如果是" i " 的话,那么在首页就显示 “……文字文字<p>文字文字文字文字文字<i” 这样的话就出错了!
还有,如果刚刚好截取的是字符" <p>" 或者是" <br />" ,或许会出现只截取了 "<" 、"<p" 、 "<b"、"<br"、"<br / " 之类的情况。
请问各位高手怎么解决这种情况!!
说明:显示内容里种保留<img> <p> <br /> 这三个html标签。
如果用户选择的是在首页显示300个字的话就有可能出现这样一个问题:
如果文章的内容是这样的 “……文字文字文<p>字文字文字文字文字<img src=sss.jpg><br />……” ,第300个字符如果是" i " 的话,那么在首页就显示 “……文字文字<p>文字文字文字文字文字<i” 这样的话就出错了!
还有,如果刚刚好截取的是字符" <p>" 或者是" <br />" ,或许会出现只截取了 "<" 、"<p" 、 "<b"、"<br"、"<br / " 之类的情况。
请问各位高手怎么解决这种情况!!
说明:显示内容里种保留<img> <p> <br /> 这三个html标签。
按规则分开,得到数组
$str_array = array("……文字文字文 ","<p>"," 字文字文字文字文字 ","<img src=sss.jpg>"," ","<br />"," ……");$new_str = "";foreach($str_array as $s){
if( $new_str.$s 的长度 < 300 ){
$new_str .= $s;
}
else if($s 为 html 标签){
$new_str .= $s;
break; //截取完成
}else{
$new_str = 截取300字符($new_str.$s);
break; //截取完成
}
}
截取的时候长度为300+标记的个数
输出的时候如果遇到特定标记就输出对应数组的内容
因为是按顺序取的标记,所以特定标记不用标出位置,只要在输出时设个变量控制顺序输出即可比如 <p>文字.....</p><img scr=sss.jpg>....文字<br><font color=red>文字处理</p>
就可替换成
#文字.....##....文字##文字处理#
对应数组
就是
array
0=><p>
1=></p>
2=><img src=sss.jpg>
3=><br>
4=><font color=red>
5=</p>设个变量如$i
输出的时候遇到#就输出$i,并将$i++
直到输出结束标记一定要用特殊点的在文章中不会出现的符号来分隔,不然输出的时候会引起标记位置错误
截取的时候长度为300+标记的个数
输出的时候如果遇到特定标记就输出对应数组的内容
因为是按顺序取的标记,所以特定标记不用标出位置,只要在输出时设个变量控制顺序输出即可比如 <p>文字.....</p><img scr=sss.jpg>....文字<br><font color=red>文字处理</p>
就可替换成
#文字.....##....文字##文字处理#
对应数组
就是
array
0=><p>
1=></p>
2=><img src=sss.jpg>
3=><br>
4=><font color=red>
5=</p>设个变量如$i
输出的时候遇到#就输出$i,并将$i++
直到输出结束标记一定要用特殊点的在文章中不会出现的符号来分隔,不然输出的时候会引起标记位置错误
<?$len = 29;
$string = "aaaaaaaaaa<br />bbbbbbbbbb<br />cccccccccc<br />dddddddddd<br />eeeeeeeeee";echo substr($string,0,$len); // Result: aaaaaaaaaa<br />bbbbbbbbbb<br
echo "\n";
echo cut_without_tags($string,$len); // Result: aaaaaaaaaa<br />bbbbbbbbbb<br />ccccccccc/** Function Start,[email protected] **/
function cut_without_tags($string,$len){
/*
Split $string to array:
"aaaaaaaaaa","<br />","bbbbbbbbbb","<br />","cccccccccc","<br />","dddddddddd","<br />","eeeeeeeeee"
*/
$spchar = chr(1).chr(2).chr(4); // A special String
$s = str_replace("<","$spchar<",$string);
$s = str_replace(">",">$spchar",$s);
$str_array = split("$spchar",$s);
$new_str = "";
$new_str_len = 0;
$temp_lem = 0;
foreach($str_array as $s){
$tag = strrchr($s,'<')?true:false; // Is a HTML tag?
if(!$tag) $temp_lem += strlen($s); // valid length,if NOT a HTML tag if( $temp_lem < $len ){
$new_str .= $s;
$new_str_len = $temp_lem;
}else if($new_str_len==$len || $tag){
$new_str .= $s;
$new_str_len = $temp_lem;
break;
}else{
$new_str .= substr($s,0,$len-$new_str_len); //Cut, if too long and NOT a HTML tag
break;
}
}
return $new_str;
}
?>
中文的截取算法一样,但长度的计算 strlen() 和 截取 substr() 要换成中文的函数.
还有,如果刚刚好截取的是字符 " <p> " 或者是 " <br /> " ,或许会出现只截取了 " < " 、 " <p " 、 " <b "、 " <br "、 " <br / " 之类的情况。 =================================================================================根据如上的话,我当你宽字符截取的问题已经解决了,现在的问题只是文本中参杂了一些标签,在截取的时候无法完全排除,想要去除标签,其实我感觉strip_tags()就可以啊,先去了标签,然后再截取呗