真正根据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
图书管理程序(一)
Oct 09 PHP
php获取地址栏信息的代码
Oct 08 PHP
PHP实现读取一个1G的文件大小
Aug 24 PHP
PHP中的Memcache详解
Apr 05 PHP
封装ThinkPHP的一个文件上传方法实例
Oct 31 PHP
PHP经典面试题集锦
Mar 19 PHP
Laravel 5 框架入门(二)构建 Pages 的管理功能
Apr 09 PHP
php基于openssl的rsa加密解密示例
Jul 11 PHP
PHP入门教程之使用Mysqli操作数据库的方法(连接,查询,事务回滚等)
Sep 11 PHP
php安装php_rar扩展实现rar文件读取和解压的方法
Nov 17 PHP
PHP+redis实现的限制抢购防止商品超发功能详解
Sep 19 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 ss7.5的数据调用 (笔记)
2010/03/08 PHP
php 随机排序广告的实现代码
2011/05/09 PHP
PHP 中魔术常量的实例详解
2017/10/26 PHP
Laravel框架查询构造器 CURD操作示例
2019/09/04 PHP
通过身份证号得到出生日期和性别的js代码
2009/11/23 Javascript
Jquery实战_读书笔记1—选择jQuery
2010/01/22 Javascript
js处理自己不能定义二维数组的方法详解
2014/03/03 Javascript
Node.js编码规范
2014/07/14 Javascript
使表格的标题列可左右拉伸jquery插件封装
2014/11/24 Javascript
ionic隐藏tabs的方法
2016/08/29 Javascript
获取jqGrid中选择的行的数据
2016/11/30 Javascript
JavaScript中三种常见的排序方法
2017/02/24 Javascript
JS三目运算(三元运算)方法详解
2017/03/01 Javascript
JS动态修改网页body的背景色实例代码
2017/10/07 Javascript
JS实现动态生成html table表格的方法分析
2018/07/11 Javascript
傻瓜式解读koa中间件处理模块koa-compose的使用
2018/10/30 Javascript
JS实现求5的阶乘示例
2019/01/21 Javascript
SSM+layUI 根据登录信息显示不同的页面方法
2019/09/20 Javascript
在vue中实现某一些路由页面隐藏导航栏的功能操作
2020/09/21 Javascript
design vue 表格开启列排序的操作
2020/10/28 Javascript
[44:40]Spirit vs Navi Supermajor小组赛 A组败者组第一轮 BO3 第一场 6.2
2018/06/03 DOTA
浅析Python中的多进程与多线程的使用
2015/04/07 Python
下载python中Crypto库报错:ModuleNotFoundError: No module named ‘Crypto’的解决
2018/04/23 Python
python3.7.0的安装步骤
2018/08/27 Python
python绘制规则网络图形实例
2019/12/09 Python
Python如何存储数据到json文件
2020/03/09 Python
python sitk.show()与imageJ结合使用常见的问题
2020/04/20 Python
智能室内花园:Click & Grow
2021/01/29 全球购物
银行职员思想汇报
2013/12/31 职场文书
就业协议书范本
2014/04/11 职场文书
商业计算机应用专业自荐书
2014/06/09 职场文书
目标责任书格式
2014/07/28 职场文书
刑事辩护授权委托书
2014/09/13 职场文书
Django显示可视化图表的实践
2021/05/10 Python
MySQL系列之五 视图、存储函数、存储过程、触发器
2021/07/02 MySQL
Redis高并发防止秒杀超卖实战源码解决方案
2021/11/01 Redis