真正根据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 相关文章推荐
解决dede生成静态页和动态页转换的一些问题,及火车采集入库生成动态的办法
Mar 29 PHP
常用的php ADODB使用方法集锦
Mar 25 PHP
PHP分页显示制作详细讲解
Nov 19 PHP
PHP中=赋值操作符对不同数据类型的不同行为
Jan 02 PHP
PHP curl模拟浏览器采集阿里巴巴的实现代码
Apr 20 PHP
php读取文件内容的三种可行方法示例介绍
Feb 08 PHP
通过curl模拟post和get方式提交的表单类
Apr 23 PHP
php实现的太平洋时间和北京时间互转的自定义函数分享
Aug 19 PHP
PHP实现linux命令tail -f
Feb 22 PHP
PHP上传图片类显示缩略图功能
Jun 30 PHP
tp5(thinkPHP5)框架实现多数据库查询的方法
Jan 10 PHP
php下的原生ajax请求用法实例分析
Feb 28 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
redis 队列操作的例子(php)
2012/04/12 PHP
设置php页面编码的两种方法示例介绍
2014/03/03 PHP
php通过baihui网API实现读取word文档并展示
2015/06/22 PHP
php基于CodeIgniter实现图片上传、剪切功能
2016/05/14 PHP
PHP 传输会话curl函数的实例详解
2017/09/12 PHP
php进程daemon化的正确实现方法
2018/09/06 PHP
javascript 闭包疑问
2010/12/30 Javascript
jQuery 名称冲突的解决方法
2011/04/08 Javascript
js动态为代码着色显示行号
2013/05/29 Javascript
javascript实现des解密加密全过程
2014/04/03 Javascript
详解JavaScript中Hash Map映射结构的实现
2016/05/21 Javascript
谈谈JavaScript中的几种借用方法
2016/08/09 Javascript
js实现右键菜单功能
2016/11/28 Javascript
JavaScript函数中的this四种绑定形式
2017/08/15 Javascript
Vue DevTools调试工具的使用
2017/12/05 Javascript
vue2 拖动排序 vuedraggable组件的实现
2019/08/08 Javascript
Angular8基础应用之表单及其验证
2019/08/11 Javascript
JS中队列和双端队列实现及应用详解
2020/09/29 Javascript
python连接mysql实例分享
2016/10/09 Python
解决pycharm回车之后不能换行或不能缩进的问题
2019/01/16 Python
Python面向对象程序设计多继承和多态用法示例
2019/04/08 Python
.dcm格式文件软件读取及python处理详解
2020/01/16 Python
Python同时处理多个异常的方法
2020/07/28 Python
匈牙利超级网上商店和优惠:Alza.hu
2019/12/17 全球购物
项目工作说明书
2014/07/29 职场文书
学生会感恩节活动方案
2014/10/11 职场文书
私用公车造成事故检讨书
2014/11/16 职场文书
导游欢送词
2015/01/31 职场文书
拾金不昧通报表扬范文
2015/05/05 职场文书
写给女朋友的检讨书
2015/05/06 职场文书
上甘岭观后感
2015/06/10 职场文书
分析Netty直接内存原理及应用
2021/06/14 Java/Android
CSS 伪元素::marker详解
2021/06/26 HTML / CSS
Redis集群新增、删除节点以及动态增加内存的方法
2021/09/04 Redis
Python3.8官网文档之类的基础语法阅读
2021/09/04 Python
使用vue判断当前环境是安卓还是IOS
2022/04/12 Vue.js