php截断字符串用的是substr,但是这个是无法截断中文的,原因就是中文是采用多字节编码。这里说一下针对utf8编码的汉字截断原理。
UTF-8的编码规则是这样的
1)对于单字节的符号,字节的第一位(字节的最高位)设为0,后面7位为这个符号的unicode码。因此对于英语字母,UTF-8编码和ASCII码是相同的。
2)对于n字节的符号(n>1),第一个字节的前n位都设为1,第n+1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的unicode码。
下表总结了编码规则,字母x表示可用编码的位。
UTF-8编码方式(十六进制) | 十进制|(二进制)
—————+———————————————————————
0000 0000-0000 007F |0 – 127 | 0xxxxxxx
0000 0080-0000 07FF |192 – 223 |110xxxxx 10xxxxxx
0000 0800-0000 FFFF |224 – 239 |1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF |240 – 247 |11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
更详细的可以去看看utf8编码原理
知道了编码规则,那也就可以针对utf8编码来写出截断函数了。
要用到的函数有
strlen()
计算字符串长度
substr()
单字节截断字符串
ord()
获取字符的ascii码
我们要做的就是遍历字符串的字节数,根据ascii的值有针对性的截断,最后再拼出一个截断后的字符串
首先看看下面代码输出了什么
$str = "你好"; $len = strlen($str);//计算字符串长度 $i = 0; while( $i<$len ){ echo $ascii = ord($str[$i]);//计算ascii值 echo "\n"; $i++; }
结果是
228 189 160 229 165 189
可以看到,你好这两个字每一个字都是由多个字节构成的,至于是两个,三个,四个我们却不知道了,不过只要知道,这个文字的第一个ascii的范围,我们就知道这个汉字是由多少字节组成了。
你好,你字的第一位是228,可以看到是在第三个区间,因此你是三个字节编码,228 189 160 表示“你”,下面是229,同样在第三个区间,229 165 189表示“好”。
根据编码规则,我们很容易就能够写出字符串截断函数了
找到这个汉字的字节长度,然后截取对应的长度,整个汉字就被截取下来了,接着找下一个,就这样,一个utf8字符串截取的函数就完成了
下面写了一个
/** * utf8_substr 一个简单地中文截断函数 * * @param string $str 等待截断的utf8字符串 * @param int $start 起始位置 * @param int $sublen 截断长度 * @return str 新的字符串 */ function utf8_substr($str,$start,$sublen){ $len = strlen($str); $i = 0; $newstr = ''; $strpos = 1; while( $i < $len ){ $ascii = ord($str[$i]); $end = 1; if( $ascii >= 192 && $ascii <= 223 ){ $end = 2; } if( $ascii >=224 && $ascii <=239 ){ $end = 3; } if( $ascii >=240 && $ascii <= 247 ){ $end = 4; } //从大于起始长度开始截取 if( $strpos > $start ){ $newstr .= substr($str, $i, $end); } $i += $end; $strpos += 1; //超出长度则跳出 if( ($strpos-$start) > $sublen) break; } echo $newstr; } //用法 utf8_substr("你asdas",0,3); //这个将会输出"你as"!
你可能还喜欢下面这些文章
shell中的if语法是最让我头疼的语法之一,它的判断就向使用USB插头一样——拿起来插入不行,翻转再插入还不行,再翻转插入行了!为了搞清楚这部分语言,我收集了一些文章关于if条件判断的用法,希望对你也有些帮助。一、基本语法if [ command ]; then 符合该条件执行的语句fiif [ command ];then 符合该条件执行的语句elif [ command ];then 符合该条件执行的语句else 符合该条件执行的语句fi语法说明bash shell会按顺序执行if语句,如果command执行后且它的返回状态是0,则会执行符合该条件执行的语
赞赏微信赞赏
支付宝赞赏