真正根据utf8编码的规律来进行截取字符串的函数(utf8版sub_str )

Shanon ·
更新时间:2024-09-20
· 813 次阅读

代码如下:
/*
* 功能: 作用跟substr一样,除了它不会造成乱码
* 参数:
* 返回:
*/
function utf8_substr( $str , $start , $length=null ){
// 先正常截取一遍.
$res = substr( $str , $start , $length );
$strlen = strlen( $str );
/* 接着判断头尾各6字节是否完整(不残缺) */
// 如果参数start是正数
if ( $start >= 0 ){
// 往前再截取大约6字节
$next_start = $start + $length; // 初始位置
$next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start;
$next_segm = substr( $str , $next_start , $next_len );
// 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节
$prev_start = $start - 6 > 0 ? $start - 6 : 0;
$prev_segm = substr( $str , $prev_start , $start - $prev_start );
}
// start是负数
else{
// 往前再截取大约6字节
$next_start = $strlen + $start + $length; // 初始位置
$next_len = $next_start + 6 <= $strlen ? 6 : $strlen - $next_start;
$next_segm = substr( $str , $next_start , $next_len );
// 如果第1字节就不是 完整字符的首字节, 再往后截取大约6字节.
$start = $strlen + $start;
$prev_start = $start - 6 > 0 ? $start - 6 : 0;
$prev_segm = substr( $str , $prev_start , $start - $prev_start );
}
// 判断前6字节是否符合utf8规则
if ( preg_match( '@^([\x80-\xBF]{0,5})[\xC0-\xFD]?@' , $next_segm , $bytes ) ){
if ( !empty( $bytes[1] ) ){
$bytes = $bytes[1];
$res .= $bytes;
}
}
// 判断后6字节是否符合utf8规则
$ord0 = ord( $res[0] );
if ( 128 <= $ord0 && 191 >= $ord0 ){
// 往后截取 , 并加在res的前面.
if ( preg_match( '@[\xC0-\xFD][\x80-\xBF]{0,5}$@' , $prev_segm , $bytes ) ){
if ( !empty( $bytes[0] ) ){
$bytes = $bytes[0];
$res = $bytes . $res;
}
}
}
return $res;
}

测试数据::
代码如下:
<?php
$str = 'dfjdjf测13f试65&2数据fdj(1就mfe&……就';
var_dump( utf8_substr( $str , 22 , 12 ) ); echo ' <br /> ';
var_dump( utf8_substr( $str , 22 , -6 ) ); echo ' <br /> ';
var_dump( utf8_substr( $str , 9 , 12 ) ); echo ' <br /> ';
var_dump( utf8_substr( $str , 19 , 12 ) ); echo ' <br /> ';
var_dump( utf8_substr( $str , 28 , -6 ) ); echo ' <br /> ';

显示结果::(截取无乱码, 欢迎大家测试, 提交bug)
string(12) "据fdj"
string(26) "据fdj(1就mfe&…"
string(13) "13f试65&2数"
string(12) "数据fd"
string(20) "dj(1就mfe&…" 您可能感兴趣的文章:Oracle将字符编码从GBK转到UTF8,如何操作比较稳妥?php字符编码转换之gb2312转为utf8PHP截断标题且兼容utf8和gb2312编码JoshChen_web格式编码UTF8-无BOM的小细节分析js 编码转换 gb2312 和 utf8 互转的2种方法基于php导出到Excel或CSV的详解(附utf8、gbk 编码转换)MySql修改数据库编码为UTF8避免造成乱码问题PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码php验证手机号码(支持归属地查询及编码为UTF8)查看修改mysql编码方式让它支持中文(gbk或者utf8)多种语言(big5\gbk\gb2312\utf8\Shift_JIS\iso8859-1)的网页编码切换解决方案归纳Mysql数据库编码问题 (修改数据库,表,字段编码为utf8)ASP关于编码的几个有用的函数小结(utf8)XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)PHP UTF8编码内的繁简转换类UTF8编码内的繁简转换的PHP类PHP 截取字符串 分别适合GB2312和UTF8编码情况utf8编码检测方法分享



编码 str 截取字符串 字符串 函数 utf8 sub 字符

需要 登录 后方可回复, 如果你还没有账号请 注册新账号