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


Posted in PHP onOctober 24, 2012
/* 
* 功能: 作用跟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&…"
PHP 相关文章推荐
PHP序列号生成函数和字符串替换函数代码
Jun 07 PHP
Could not load type System.ServiceModel.Activation.HttpModule解决办法
Dec 29 PHP
解析link_mysql的php版
Jun 30 PHP
php遍历文件夹和文件列表示例分享
Mar 11 PHP
php使用PDO操作MySQL数据库实例
Dec 30 PHP
微信自定义菜单的处理开发示例
Apr 16 PHP
php实现登录tplink WR882N获取IP和重启的方法
Jul 20 PHP
PHP读取文件的常见几种方法
Nov 03 PHP
CMSPRESS 10行代码搞定 PHP无限级分类2
Mar 30 PHP
360搜索引擎自动收录php改写方案
Apr 28 PHP
PHP实现会员账号单唯一登录的方法分析
Mar 07 PHP
laravel实现按时间日期进行分组统计方法示例
Mar 23 PHP
php中检查文件或目录是否存在的代码小结
Oct 22 #PHP
php模拟js函数unescape的函数代码
Oct 20 #PHP
PHP 万年历实现代码
Oct 18 #PHP
php页面缓存ob系列函数介绍
Oct 18 #PHP
php cc攻击代码与防范方法
Oct 18 #PHP
php shell超强免杀、减少体积工具实现代码
Oct 16 #PHP
PHP中替换换行符的几种方法小结
Oct 15 #PHP
You might like
深入HTTP响应状态码速查表的详解
2013/06/07 PHP
php导出生成word的方法
2015/12/25 PHP
thinkphp多层MVC用法分析
2015/12/30 PHP
基于jQuery的简单的列表导航菜单
2011/03/02 Javascript
一款jquery特效编写的大度宽屏焦点图切换特效的实例代码
2013/08/05 Javascript
Jquery焦点与失去焦点示例应用
2014/06/10 Javascript
浏览器中url存储的JavaScript实现
2015/07/07 Javascript
JS判断页面是否出现滚动条的方法
2015/07/17 Javascript
AngularJS过滤器filter用法实例分析
2016/11/04 Javascript
Angular.js实现注册系统的实例详解
2016/12/18 Javascript
浅谈Vue的基本应用
2016/12/27 Javascript
Bootstrap fileinput文件上传组件使用详解
2017/06/06 Javascript
react实现一个优雅的图片占位模块组件详解
2017/10/30 Javascript
javascript中的相等操作符(==与===区别)
2019/12/21 Javascript
详解vue3.0 的 Composition API 的一种使用方法
2020/10/26 Javascript
Python打印斐波拉契数列实例
2015/07/07 Python
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
Python3.7实现中控考勤机自动连接
2018/08/28 Python
浅谈django的render函数的参数问题
2018/10/16 Python
python 列表转为字典的两个小方法(小结)
2019/06/28 Python
Python实现微信翻译机器人的方法
2019/08/13 Python
Tensorflow读取并输出已保存模型的权重数值方式
2020/01/04 Python
解决ROC曲线画出来只有一个点的问题
2020/02/28 Python
Python如何用wx模块创建文本编辑器
2020/06/07 Python
HTML+CSS3 模仿Windows7 桌面效果
2010/06/17 HTML / CSS
美国最受欢迎的度假租赁网站:VRBO
2016/08/02 全球购物
小学生中国梦演讲稿
2014/04/23 职场文书
优秀的个人求职信范文
2014/05/09 职场文书
小学师德标兵先进事迹材料
2014/05/25 职场文书
2014七年级班主任工作总结
2014/12/05 职场文书
高中生打架检讨书1000字
2015/02/17 职场文书
工作自我评价范文
2015/03/05 职场文书
2015年征兵工作总结
2015/07/23 职场文书
2016关于预防职务犯罪的心得体会
2016/01/21 职场文书
java设计模式--七大原则详解
2021/07/21 Java/Android
Nginx 502 bad gateway错误解决的九种方案及原因
2022/08/14 Servers