真正根据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 xfocus防注入资料
Apr 27 PHP
写php分页时出现的Fatal error的解决方法
Apr 18 PHP
PHP获取文件绝对路径的代码(上一级目录)
May 29 PHP
PHP仿博客园 个人博客(1) 数据库与界面设计
Jul 05 PHP
两千行代码的PHP学习笔记汇总
Oct 05 PHP
PHP抓取网页、解析HTML常用的方法总结
Jul 01 PHP
php实现XSS安全过滤的方法
Jul 29 PHP
PHPStrom中实用的功能和快捷键大全
Sep 23 PHP
CI框架(CodeIgniter)公共模型类定义与用法示例
Aug 10 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
Feb 23 PHP
Laravel核心解读之异常处理的实践过程
Feb 24 PHP
PHP 判断字符串是中文还是英文, 或者是中英混合
Mar 09 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知道与问问的采集插件代码
2010/10/12 PHP
全新的PDO数据库操作类php版(仅适用Mysql)
2012/07/22 PHP
PHP使用feof()函数读文件的方法
2014/11/07 PHP
php实现通用的信用卡验证类
2015/03/24 PHP
PHP设计模式之适配器模式定义与用法详解
2018/04/03 PHP
laravel 修改.htaccess文件 重定向public的解决方法
2019/10/12 PHP
php封装实现钉钉机器人报警接口的示例代码
2020/08/08 PHP
用jQuery扩展自写的 UI导航
2010/01/13 Javascript
javascript题目,重写函数让其无限相加
2012/02/15 Javascript
深入了解javascript中的prototype与继承
2013/04/14 Javascript
JavaScript中string转换成number介绍
2014/12/31 Javascript
Vuejs第十二篇之动态组件全面解析
2016/09/09 Javascript
微信小程序 教程之注册页面
2016/10/17 Javascript
react-router实现按需加载
2017/05/09 Javascript
vue中的非父子间的通讯问题简单的实例代码
2017/07/19 Javascript
vue-cli3.0如何使用CDN区分开发、生产、预发布环境
2018/11/22 Javascript
小程序的上传文件接口的注意要点解析
2019/09/17 Javascript
JavaScript实现京东快递单号查询
2020/11/30 Javascript
Python设计足球联赛赛程表程序的思路与简单实现示例
2016/06/28 Python
python爬虫系列Selenium定向爬取虎扑篮球图片详解
2017/11/15 Python
Django实现分页功能
2018/07/02 Python
将python文件打包成EXE应用程序的方法
2019/05/22 Python
python输出电脑上所有的串口名的方法
2019/07/02 Python
浅析PEP572: 海象运算符
2019/10/15 Python
Python创建数字列表的示例
2019/11/28 Python
JAVA中的关键字有什么特点
2014/03/07 面试题
什么是组件架构
2016/05/15 面试题
公务员职务工作的自我评价
2013/11/01 职场文书
网络教育自我鉴定
2013/11/01 职场文书
我是一名护士演讲稿
2014/08/28 职场文书
法制教育演讲稿
2014/09/10 职场文书
党校个人总结
2015/03/04 职场文书
小区保洁员岗位职责
2015/04/10 职场文书
给校长的建议书作文300字
2015/09/14 职场文书
Python正则表达式中flags参数的实例详解
2022/04/01 Python
聊聊mysql都有哪几种分区方式
2022/04/13 MySQL