<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://www.jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://www.jackxiang.com/post//</link>
<title><![CDATA[[原]utf-8编码的汉字str用php截断的正确方法【精华】]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Tue, 28 Jul 2009 03:52:22 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	2007年12月05日 星期三 下午 04:14<br/>keywords：substr，substr utf-8 gbk gb2312 编码<br/><br/>STEP 1:<br/>utf-8是变长的unicode编码。<br/>以下是unicode和utf8对应关系<br/>U-00000000 - U-0000007F: 0xxxxxxx [1 byte]<br/>U-00000080 - U-000007FF: 110xxxxx 10xxxxxx&nbsp;&nbsp; [2 byte]<br/>U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx&nbsp;&nbsp; [3 byte]<br/>U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx&nbsp;&nbsp; [4 btye]<br/>U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx&nbsp;&nbsp; [5 byte]<br/>U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx [6 byte]<br/>可以看出utf-8编码的数据其byte可以分为3类：0xxxxxxx，10xxxxxx和1110xxxx(再大的也归这类,很少使用)；<br/>A类 字节值小于127(--0x80)，一个字节即表示一个字，例如：数字以及大小写字母；<br/>B类 字节值在128(0x80)和192(0xC0)之间的。该类字节只有后6位有效，不能单独存在，必须和前面字节连起来才能表示一个完整的字符，处理不当就产生乱码。<br/>C类 字节值大于192(0xC0++)的。该类字节如果小于224(0xE0,也就是11000000-11011111,定小于1110xxxx)那么它应和下一个字节(B类)后6位连起来才能用。若小于240(0xF0,也就是1110xxxx)则需和后两个字节连用。以此类推。<br/><br/>UTF与unicode的关系:<br/>Unicode是一个字符集, 可以看作为内码.而UTF 是一种编码方式, 它的出现是因为unicode不适宜在某些场合直接传输和处理. UTF-16直接就是unicode编码, 没有变换, 但它包含了0x00在编码内, 头256字节码的第一个byte都是0x00, 在操作系统(C语言)中有特殊意义, 会引起问题. 采用UTF-8编码对unicode的直接编码作些变换可以避免这问题, 并带来一些优点.<br/><br/>STEP 2: 汉字编码规范：<br/>BIG5=繁体中文<br/>GB2312＝ASCII＋常用汉字＋符号<br/>GBK＝GB2312＋不常用字（含BIG5繁体汉字）＋图形符号<br/>GB18030＝GBK＋Ext-A＋藏、蒙、维吾尔等文字<br/><br/>向上兼容，中文Windows的缺省内码还是GBK，但是Unicode只与ASCII兼容(ISO-8859-1)，与GBK码不兼容，需要根据编码表做转换。<br/><br/>所以，对于汉字的GBK编码是这样表示的：把一个汉字用两个字节来表示，其首字节对应0x81-0xFE(即129-224)，尾字节对应除掉 (0x7F)的0x40-oxFE(即64-126和128-224)。汉字的GBK编码首字节的起始编码0x81，其二进制即为0000 1000 0000 0000，可见若一个字符的二进制逻辑与0x81之后为0时，该字符一定小于0x81，此时该字符必定不是汉字，反之，该字符应该是一个汉字的首字节。<br/><br/>下面是网上找到的一个中英文混合字符串的截取的常用代码：<br/><br/>function gb_substr($str, $start, $len)<br/>&#123;<br/>$s = '';<br/>$j = 0;<br/>for ($i=0; $i<strlen($str); $i++) &#123;<br/>if (ord($str[$i]) & 0x81 != 0) &#123; //或ord($str[$i]) > '0x80'<br/>&nbsp;&nbsp; $t = $str[$i].$str[$i+1];<br/>&nbsp;&nbsp; if (($i >= $start) && ($i+1 < $start+$len)) $s.= $t;<br/>&nbsp;&nbsp; $i++;<br/>&#125; else &#123;<br/>&nbsp;&nbsp; $t = $str[$i];<br/>&nbsp;&nbsp; if (($i >= $start) && ($i < $start+$len)) $s.= $t;<br/>&#125;<br/>if ($i >= $start+$len) break;<br/>&#125;<br/>return $s;<br/>&#125;<br/><br/>STEP 3:utf-8编码的字串截取函数实现<br/>PHP中没有函数可用，substr()力不从心，又因为UTF-8分别有1,2,3字节编码，中日韩文都是3字节编码，处理时根据字符编码中首字节大小区分字节数量。<br/>下面是我的博客中用到的处理函数：<br/>function substr_cn($str,$start=0,$len)<br/>&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;$strlen=strlen($str);<br/>&nbsp;&nbsp;&nbsp;&nbsp;for($i=0;$i<$strlen;$i++)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if($i>=$start&&$i<($start+$len))<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(ord(substr($str,$i,1))>'0xE0')<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmpstr.=substr($str,$i,3);&nbsp;&nbsp;&nbsp;&nbsp;//utf-8 code<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$i=$i+2;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$tmpstr.=substr($str,$i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;if(strlen($tmpstr)>$len)<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $len--;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return substr_cn($str,$start,$len);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/><br/>&nbsp;&nbsp;&nbsp;&nbsp;return $tmpstr;<br/>&#125;<br/><br/>STEP 4:相关的一个完整函数供研究使用：<br/>function cut_str($sourcestr,$cutlength)<br/>&#123;<br/>&nbsp;&nbsp; $returnstr='';<br/>&nbsp;&nbsp; $i=0;<br/>&nbsp;&nbsp; $n=0;<br/>&nbsp;&nbsp; $str_length=strlen($sourcestr);//字符串的字节数<br/>&nbsp;&nbsp; while (($n<$cutlength) and ($i<=$str_length))<br/>&nbsp;&nbsp; &#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$temp_str=substr($sourcestr,$i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$ascnum=Ord($temp_str);//得到字符串中第$i位字符的ascii码<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if ($ascnum>=224)&nbsp;&nbsp;&nbsp;&nbsp;//如果ASCII位高与224，<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $returnstr=$returnstr.substr($sourcestr,$i,3); //根据UTF-8编码规范，将3个连续的字符计为单个字符&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $i=$i+3;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//实际Byte计为3<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $n++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//字串长度计1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elseif ($ascnum>=192) //如果ASCII位高与192，<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $returnstr=$returnstr.substr($sourcestr,$i,2); //根据UTF-8编码规范，将2个连续的字符计为单个字符<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $i=$i+2;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//实际Byte计为2<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $n++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//字串长度计1<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;elseif ($ascnum>=65 && $ascnum<=90) //如果是大写字母，<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $returnstr=$returnstr.substr($sourcestr,$i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $i=$i+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//实际的Byte数仍计1个<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $n++;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//但考虑整体美观，大写字母计成一个高位字符<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;else&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//其他情况下，包括小写字母和半角标点符号，<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $returnstr=$returnstr.substr($sourcestr,$i,1);<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $i=$i+1;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//实际的Byte数计1个<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; $n=$n+0.5;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//小写字母和半角标点等与半个高位字符宽...<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp; &#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ($str_length>$cutlength)&#123;<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$returnstr = $returnstr . "...";//超过长度时在尾处加上省略号<br/>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&#125;<br/>&nbsp;&nbsp;&nbsp;&nbsp;return $returnstr;<br/><br/>&#125;
]]>
</description>
</item><item>
<link>http://www.jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [原]utf-8编码的汉字str用php截断的正确方法【精华】]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://www.jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>