真正根据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企业级应用之常见缓存技术篇
Jan 27 PHP
服务器变量 $_SERVER 的深入解析
Jul 02 PHP
Linux下创建nginx脚本-start、stop、reload…
Aug 03 PHP
ThinkPHP中公共函数路径和配置项路径的映射分析
Nov 22 PHP
php调用KyotoTycoon简单实例
Apr 02 PHP
php页面,mysql数据库转utf-8乱码,utf-8编码问题总结
Aug 27 PHP
apache和PHP如何整合在一起
Oct 12 PHP
Zend Framework教程之Zend_Db_Table表关联实例详解
Mar 23 PHP
浅谈PHPANALYSIS提取关键字
Mar 08 PHP
YII框架常用技巧总结
Apr 27 PHP
微信推送功能实现方式图文详解
Jul 12 PHP
在Laravel中实现使用AJAX动态刷新部分页面
Oct 15 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
详解WordPress中创建和添加过滤器的相关PHP函数
2015/12/29 PHP
php微信开发接入
2016/08/27 PHP
PHP目录操作实例总结
2016/09/27 PHP
PHP读取文件的常见几种方法
2016/11/03 PHP
PHP实现数据库统计时间戳按天分组输出数据的方法
2017/10/10 PHP
jquery 提交值不为空的元素示例代码
2013/05/10 Javascript
js实现浏览器的各种菜单命令比如打印、查看源文件等等
2013/10/24 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
JQuery伸缩导航练习示例
2013/11/13 Javascript
Jquery自定义button按钮的几种方法
2014/06/11 Javascript
jquery访问ashx文件示例代码
2014/08/11 Javascript
jQuery的context属性用法实例
2014/12/27 Javascript
javascript电商网站抢购倒计时效果实现
2015/11/19 Javascript
XML、HTML、CSS与JS的区别整理
2016/02/18 Javascript
jQuery unbind 删除绑定事件详解
2016/05/24 Javascript
微信小程序商城项目之商品属性分类(4)
2017/04/17 Javascript
微信小程序上线发布流程图文详解
2019/05/06 Javascript
jquery实现进度条状态展示
2020/03/26 jQuery
jquery+css3实现的经典弹出层效果示例
2020/05/16 jQuery
[02:50]【扭转乾坤,只此一招】DOTA2永雾林渊版本开启新篇章
2020/12/22 DOTA
Python实现将xml导入至excel
2015/11/20 Python
pygame游戏之旅 添加游戏界面按键图形
2018/11/20 Python
django的settings中设置中文支持的实现
2019/04/28 Python
Python实现Selenium自动化Page模式
2019/07/14 Python
对Python 中矩阵或者数组相减的法则详解
2019/08/26 Python
Python Handler处理器和自定义Opener原理详解
2020/03/05 Python
阿联酋电子产品购物网站:Menakart
2017/09/15 全球购物
SteelSeries赛睿官网:游戏外设和配件的领先制造商(耳机、键盘、鼠标和鼠标垫)
2018/06/17 全球购物
River Island美国官网:英国高街时尚品牌
2018/09/04 全球购物
大学国际贸易专业自荐信
2014/06/05 职场文书
大学四年个人总结
2015/03/03 职场文书
敬老院志愿者活动总结
2015/05/06 职场文书
史上最全的军训拉歌口号
2015/12/25 职场文书
工作违纪的检讨书范文
2019/07/09 职场文书
关于感恩的素材句子(38句)
2019/11/11 职场文书
clear 万能清除浮动(clearfix:after)
2023/05/21 HTML / CSS