真正根据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 判断访客是否为搜索引擎蜘蛛的函数代码
Jul 29 PHP
PHP发送短信代码分享
Aug 11 PHP
PHP的Yii框架中过滤器相关的使用总结
Mar 29 PHP
Yii2超好用的日期和时间组件(值得收藏)
May 05 PHP
Redis在Laravel项目中的应用实例详解
Aug 11 PHP
Laravel构建即时应用的一种实现方法详解
Aug 31 PHP
PHP实现广度优先搜索算法(BFS,Broad First Search)详解
Sep 16 PHP
PHP读取目录树的实现方法分析
Mar 22 PHP
关于Laravel参数验证的一些疑与惑
Nov 19 PHP
thinkphp框架实现路由重定义简化url访问地址的方法分析
Apr 04 PHP
PHP哈希表实现算法原理解析
Dec 11 PHP
PHP7 其他修改
Mar 09 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
php中HTTP_REFERER函数用法实例
2014/11/21 PHP
php 解决扫描二维码下载跳转问题
2017/01/13 PHP
解决Laravel无法使用COOKIE和SESSION的问题
2019/10/16 PHP
页面中body onload 和 window.onload 冲突的问题的解决
2009/07/01 Javascript
onkeydown事件解决按回车键直接提交数据的需求
2013/04/11 Javascript
鼠标移到导航当前位置的LI变色处于选中状态
2013/08/23 Javascript
jquery实现tr元素的上下移动示例代码
2013/12/20 Javascript
利用JQuery和Servlet实现跨域提交请求示例分享
2014/02/12 Javascript
js表单提交和submit提交的区别实例分析
2015/12/10 Javascript
Angular2 环境配置详细介绍
2016/09/21 Javascript
Javascript从数组中随机取出不同元素的两种方法
2016/09/22 Javascript
jquery插件锦集【推荐】
2016/12/16 Javascript
JS实现页面打印(整体、局部)
2017/08/18 Javascript
jquery使用iscorll实现上拉、下拉加载刷新
2017/10/26 jQuery
轻松理解vue的双向数据绑定问题
2017/10/30 Javascript
webpack 最佳配置指北(推荐)
2020/01/07 Javascript
使用 Jest 和 Supertest 进行接口端点测试实例详解
2020/04/25 Javascript
实例讲解python函数式编程
2014/06/09 Python
python中使用enumerate函数遍历元素实例
2014/06/16 Python
Python MD5加密实例详解
2017/08/02 Python
Python用for循环实现九九乘法表
2018/05/31 Python
python绘制中国大陆人口热力图
2018/11/07 Python
Python3如何实现Win10桌面自动切换
2020/08/11 Python
CSS3实现可翻转的hover效果
2018/05/23 HTML / CSS
英国最大的电子产品和家电零售企业:Currys PC World
2016/09/24 全球购物
Cotton On美国网站:澳洲时装连锁品牌
2016/10/25 全球购物
数据库笔试题
2013/05/09 面试题
一套.net面试题及答案
2016/11/02 面试题
酒店应聘自荐信
2013/11/09 职场文书
外企财务年会演讲稿
2014/01/03 职场文书
《花的勇气》教后反思
2014/02/12 职场文书
学校食堂标语
2014/10/06 职场文书
2014年社区民政工作总结
2014/12/02 职场文书
贫困生助学金感谢信
2015/01/21 职场文书
2015年社区精神文明工作总结
2015/05/26 职场文书
Java界面编程实现界面跳转
2022/06/16 Java/Android