真正根据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 相关文章推荐
如何实现给定日期的若干天以后的日期
Oct 09 PHP
在PHP中养成7个面向对象的好习惯
Jan 28 PHP
PHP中全局变量global和$GLOBALS[]的区别分析
Aug 06 PHP
win7安装php框架Yii的方法
Jan 25 PHP
简单介绍PHP非阻塞模式
Mar 03 PHP
利用PHP将图片转换成base64编码的实现方法
Sep 13 PHP
PHP实现QQ快速登录的方法
Sep 28 PHP
thinkPHP5框架auth权限控制类与用法示例
Jun 12 PHP
PHP基于rabbitmq操作类的生产者和消费者功能示例
Jun 16 PHP
php app支付宝回调(异步通知)详解
Jul 25 PHP
详解php命令注入攻击
Apr 06 PHP
gearman中worker常驻后台,导致MySQL server has gone away的解决方法
Feb 27 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读取EXCEL文件 php excelreader读取excel文件
2012/12/06 PHP
php自动加载机制的深入分析
2013/06/08 PHP
Laravel 5.3 学习笔记之 错误&amp;日志
2016/08/28 PHP
php与c 实现按行读取文件实例代码
2017/01/03 PHP
PHP CURL实现模拟登陆并上传文件操作示例
2020/01/02 PHP
使用jQuery向asp.net Mvc传递复杂json数据-ModelBinder篇
2010/05/07 Javascript
网页整体变灰白色(兼容各浏览器)实例
2013/04/21 Javascript
Javascript中call的两种用法实例
2013/12/13 Javascript
jQuery 过滤方法filter()选择具有特殊属性的元素
2014/06/15 Javascript
Nodejs异步回调的优雅处理方法
2014/09/25 NodeJs
JavaScript控制网页平滑滚动到指定元素位置的方法
2015/04/17 Javascript
JS函数arguments数组获得实际传参数个数的实现方法
2016/05/28 Javascript
javascript 分号总结及详细介绍
2016/09/24 Javascript
JS库之Particles.js中文开发手册及参数详解
2017/09/13 Javascript
详解React开发必不可少的eslint配置
2018/02/05 Javascript
node实现基于token的身份验证
2018/04/09 Javascript
JavaScript的词法结构精华篇
2018/10/17 Javascript
JavaScript解析机制与闭包原理实例详解
2019/03/08 Javascript
17道题让你彻底理解JS中的类型转换
2019/08/08 Javascript
vue表单中遍历表单操作按钮的显示隐藏示例
2019/10/30 Javascript
[04:03]DOTA2肉山黑名单梦之声 风暴之灵中文配音鉴赏
2013/07/03 DOTA
Python进程间通信之共享内存详解
2017/10/30 Python
TensorFlow 合并/连接数组的方法
2018/07/27 Python
浅析python中的迭代与迭代对象
2018/10/08 Python
python OpenCV GrabCut使用实例解析
2019/11/11 Python
python3 字符串知识点学习笔记
2020/02/08 Python
django-利用session机制实现唯一登录的例子
2020/03/16 Python
中国海淘族值得信赖的海淘返利网站:55海淘
2017/01/16 全球购物
应征英语教师求职信
2013/11/27 职场文书
校园摄影活动策划方案
2014/02/05 职场文书
2014年四风个人对照检查及整改措施
2014/10/28 职场文书
2014年银行个人工作总结
2014/12/05 职场文书
博士给导师的自荐信
2015/03/06 职场文书
基石观后感
2015/06/12 职场文书
毕业生的自我鉴定表范文
2019/05/16 职场文书
各种货币符号快捷输入
2022/02/17 杂记