真正根据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代码把全角数字转为半角数字
Dec 10 PHP
php 过滤器实现代码
Aug 09 PHP
php通过文件头检测文件类型通用代码类(zip,rar等)
Oct 19 PHP
php根据年月获取季度的方法
Mar 31 PHP
PHP 二维数组根据某个字段排序的具体实现
Jun 03 PHP
php类中的$this,static,final,const,self这几个关键字使用方法
Dec 14 PHP
CI映射(加载)数据到view层的方法
Mar 28 PHP
PHP Filter过滤器全面解析
Aug 09 PHP
谈谈PHP连接Access数据库的注意事项
Aug 12 PHP
php基于dom实现读取图书xml格式数据的方法
Feb 03 PHP
PHP中单例模式与工厂模式详解
Feb 17 PHP
2017年最新PHP经典面试题目汇总(上篇)
Mar 17 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实现详细解析
2013/08/24 PHP
PHP 函数call_user_func和call_user_func_array用法详解
2014/03/02 PHP
php超快高效率统计大文件行数
2015/07/05 PHP
js replace正则表达式应用案例讲解
2013/01/17 Javascript
JavaScript判断文件上传类型的方法
2014/09/02 Javascript
使用js dom和jquery分别实现简单增删改
2014/09/11 Javascript
js实现文章文字大小字号功能完整实例
2014/11/01 Javascript
javascript抽象工厂模式详细说明
2014/12/16 Javascript
jQuery中:last-child选择器用法实例
2014/12/31 Javascript
JavaScript实现将UPC转换成ISBN的方法
2015/05/26 Javascript
AngularJS基础 ng-keypress 指令简单示例
2016/08/02 Javascript
如何在Angular.JS中接收并下载PDF
2016/11/26 Javascript
JS解决IOS中拍照图片预览旋转90度BUG的问题
2017/09/13 Javascript
Vue常用的几个指令附完整案例
2018/11/06 Javascript
详解axios中封装使用、拦截特定请求、判断所有请求加载完毕)
2019/04/09 Javascript
node.js基于dgram数据报模块创建UDP服务器和客户端操作示例
2020/02/12 Javascript
js实现头像上传并且可预览提交
2020/12/25 Javascript
[00:05]ChinaJoy现场 DOTA2玩家高呼“CN DOTA BEST DOTA”
2019/08/04 DOTA
python实现在每个独立进程中运行一个函数的方法
2015/04/23 Python
Python使用plotly绘制数据图表的方法
2017/07/18 Python
python如何读写json数据
2018/03/21 Python
Python面向对象实现一个对象调用另一个对象操作示例
2019/04/08 Python
python输出电脑上所有的串口名的方法
2019/07/02 Python
Python如何使用turtle库绘制图形
2020/02/26 Python
Python实现获取当前目录下文件名代码详解
2020/03/10 Python
免税水晶:Duty Free Crystal
2019/05/13 全球购物
少先队学雷锋活动月总结
2014/03/09 职场文书
新年晚会主持词
2014/03/24 职场文书
二手房买卖协议书
2014/04/10 职场文书
2014教师专业技术工作总结
2014/12/03 职场文书
故宫英文导游词
2015/01/31 职场文书
综合素质评价个性发展自我评价
2015/03/06 职场文书
酒桌上的开场白
2015/06/01 职场文书
OpenCV全景图像拼接的实现示例
2021/06/05 Python
Nginx四层负载均衡的配置指南
2021/06/11 Servers
Python中npy和mat文件的保存与读取
2022/04/24 Python