真正根据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 相关文章推荐
基于mysql的bbs设计(二)
Oct 09 PHP
php购物网站支付paypal使用方法
Nov 28 PHP
php 文本文件的读取效率
Feb 10 PHP
php代码中使用换行及(\n或\r\n和br)的应用
Feb 02 PHP
windwos下使用php连接oracle数据库的过程分享
May 26 PHP
php使用COPY函数更新配置文件的方法
Jun 18 PHP
PHP 数组基本操作小结(推荐)
Jun 13 PHP
thinkphp中多表查询中防止数据重复的sql语句(必看)
Sep 22 PHP
Laravel手动分页实现方法详解
Oct 09 PHP
PHP中使用OpenSSL生成证书及加密解密
Feb 05 PHP
php实现的证件照换底色功能示例【人像抠图/换背景图】
May 29 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在线生成ico文件的代码
2007/10/09 PHP
PHP获取表单所有复选框的值的方法
2014/08/28 PHP
Laravel 5.5官方推荐的Nginx配置学习教程
2017/10/06 PHP
JS 学习笔记 防止发生命名冲突
2009/07/30 Javascript
JS 屏蔽键盘不可用与鼠标右键不可用的方法
2013/11/18 Javascript
javascript ajax的5种状态介绍
2014/08/18 Javascript
JavaScript实现大数的运算
2014/11/24 Javascript
JS日程管理插件FullCalendar中文说明文档
2017/02/06 Javascript
JavaScript实现的搜索及高亮显示功能示例
2017/08/14 Javascript
浅谈vuex之mutation和action的基本使用
2017/08/29 Javascript
Vue2.0实现调用摄像头进行拍照功能 exif.js实现图片上传功能
2018/04/28 Javascript
详解JavaScript的BUG和错误
2018/05/07 Javascript
如何利用Node.js与JSON搭建简单的动态服务器
2020/06/16 Javascript
Vue 禁用浏览器的前进后退操作
2020/09/04 Javascript
采用python实现简单QQ单用户机器人的方法
2014/07/03 Python
基于python log取对数详解
2018/06/08 Python
详解Python3 对象组合zip()和回退方式*zip
2019/05/15 Python
python获取Linux发行版名称
2019/08/30 Python
Python二维数组实现求出3*3矩阵对角线元素的和示例
2019/11/29 Python
巴西箱包、背包、钱包和旅行配件购物网站:Inovathi
2019/12/14 全球购物
英国最大的天然和有机产品在线零售商之一:Big Green Smile
2020/05/06 全球购物
化学专业毕业生自荐信
2013/11/15 职场文书
优秀英语专业毕业生求职信
2013/11/23 职场文书
考试不及格检讨书
2014/01/09 职场文书
校园新闻广播稿
2014/01/10 职场文书
吸烟检讨书2000字
2014/02/13 职场文书
公司贷款承诺书
2014/05/30 职场文书
爬山的活动方案
2014/08/16 职场文书
小学优秀教师先进事迹材料
2014/12/16 职场文书
2015年女生节活动总结
2015/02/27 职场文书
合作与交流自我评价
2015/03/09 职场文书
天鹅湖观后感
2015/06/09 职场文书
歌咏比赛主持词
2015/06/29 职场文书
Nginx同一个域名配置多个项目的实现方法
2021/03/31 Servers
MySQL创建表操作命令分享
2022/03/25 MySQL
【海涛七七解说】DCG第二周:DK VS 天禄
2022/04/01 DOTA