php mb_strwidth函数实现中英文混排字符串截取

mb_strwidth($str, $encoding) 返回字符串的宽度

$str 要计算的字符串

$encoding 要使用的编码,如 utf8、gbk

mb_strimwidth($str, $start, $width, $tail, $encoding) 按宽度截取字符串

$str 要截取的字符串

$start 从哪个位置开始截取,默认是0

$width 要截取的宽度

$tail 追加到截取字符串后边的字符串,常用的是 ...

$encoding 要使用的编码

 代码如下 复制代码

<?php
/**
 * utf8 编码格式
 * 1个中文占用3个字节
 * 我们希望的是1个中文占用2个字节,
 * 因为从宽度上看2个英文字母占用的位置相当于1个中文
 */

// 测试字符串
$str = 'aaaa啊啊aaaa啊啊啊aaa';
echo strlen($str); // 只用strlen输出为25个字节

// 必须指定编码,不然会使用php的内码 mb_internal_encoding()可以查看内码
// 使用mb_strwidth输出字符串的宽度为20使用utf8编码
echo mb_strwidth($str, 'utf8');

// 只有宽度大于10才截取
if(mb_strwidth($str, 'utf8')>10){
    // 此处设定从0开始截取,取10个追加...,使用utf8编码
    // 注意追加的...也会被计算到长度之内
    $str = mb_strimwidth($str, 0, 10, '...', 'utf8');
}

// 最后输出 aaaa啊... 4个a算4个 1个啊算2个 3个点算3个 4+2+3=9
// 是不是很简单啊,有的人说了为什么是9个不是10个吗?
// 因为正好“啊”的后边还是“啊”,中文算2个,9+2=11 超出了设定,所以去掉1个就是9了
echo $str;

如果对于全中文没有问题但如果中间有符号了就有问题了,如我使用mb_strimwidth,mb_strwidth,后发现如果标题中存在“”符号的时候,PHP mb_strwidth会将该符号认为是1个宽度,我纳闷了这个不是中文的双引号嘛,照理说肯定是宽字节的,长度应该是2个宽度,后查询“”unicode分别为u201C和u201D,不在中文字符的范围中,再查询unicode.org 的码表,发现u2000-u206F是通用符号的范围,此范围中的字符虽然都是宽字符的形式,但是PHP 的mb_函数却认为是1个宽度,没办法,只能靠自己了。

 代码如下 复制代码

function truncString($str, $length) 

$countLen=0; 
for($i=0;$i<mb_strlen($str);$i++) 

$countLen+=amb_strwidth(mb_substr($str,$i,1)); 
if($countLen>$length) 
return mb_substr($str,0,$i); 

return $str; 

function amb_strwidth($str_width) 

$count=0; 
for($i=0;$i<mb_strlen($str_width);$i++) 

//if(mb_substr($str_width,$i,1)=="\xE2\x80\x9C"||mb_substr($str_width,$i,1)=='\xE2\x80\x9D') 
//如果遇到u2000-u206F内的字符则将计数器加2 
if(preg_match("/[\x{2000}-\x{206F}]/u",mb_substr($str_width,$i,1))) 
$count+=2; 
else 
$count+=mb_strwidth(mb_substr($str_width,$i,1)); 

return $count; 
}

总结,做来做出怎么就感觉到这个变成了回原点了呢,感觉还是要使用到循环遍历算字符编码取字符位数哈。

时间: 2024-09-16 03:49:41

php mb_strwidth函数实现中英文混排字符串截取的相关文章

实现中英文混排字符串截取的php代码

提到中英文混排计数.截取,大家首先想到的是ascii.16进制.正则匹配.循环计数. 今天我给大家分享的是php的mb扩展,教你如何轻松处理字符串. 先给大家介绍用到的函数: mb_strwidth($str, $encoding) 返回字符串的宽度 $str 要计算的字符串 $encoding 要使用的编码,如 utf8.gbk mb_strimwidth($str, $start, $width, $tail, $encoding) 按宽度截取字符串 $str 要截取的字符串 $start

php轻松实现中英文混排字符串截取_php技巧

先给大家介绍用到的函数: 复制代码 代码如下: mb_strwidth($str, $encoding) 返回字符串的宽度$str 要计算的字符串$encoding 要使用的编码,如 utf8.gbk 复制代码 代码如下: mb_strimwidth($str, $start, $width, $tail, $encoding) 按宽度截取字符串$str 要截取的字符串$start 从哪个位置开始截取,默认是0$width 要截取的宽度$tail 追加到截取字符串后边的字符串,常用的是 ...$

php strlen mb_strlen计算中英文混排字符串长度_php技巧

比较strlen和mb_strlen 当字符全是英文字符的时候,两者是一样.这里主要比较一下,中英文混排的时候,两个计算结果.(测试时编码方式是UTF8) 复制代码 代码如下: <?php $str='中文a字1符'; echo strlen($str); echo '<br />'; echo mb_strlen($str,'UTF8'); //输出结果 //14 //6 ?> 结果分析:在strlen计算时,对待一个UTF8的中文字符是3个长度,所以"中文a字1符&q

php简简单单搞定中英文混排字符串截取,只需2行代码!

提到中英文混排计数.截取,大家首先想到的是ascii.16进制.正则匹配.循环计数.   今天我给大家分享的是php的mb扩展,教你如何轻松处理字符串.       先给大家介绍用到的函数:   mb_strwidth($str, $encoding) 返回字符串的宽度   $str 要计算的字符串   $encoding 要使用的编码,如 utf8.gbk   mb_strimwidth($str, $start, $width, $tail, $encoding) 按宽度截取字符串   $s

Word中如何清除中英文混排文档中的英文

为了提高个人专业技术水平,单位又让上交阶段性学习笔记.专业技术论文了,不过上有政策下有对策,同事们利用计算机点点鼠标从网上复制粘贴来完成此项工作.但有时一不留神发现搞下来的东西太高深,竟然是中英文混排的,太超过笔者的水平了,思前想后还是把这些英文都干掉的好. 在Word中单击"编辑/替换",在打开的"查找和替换"对话框中的"替换"选项卡下,单击"查找内容"框,输入[^1-^127],"替换为"框中什么也不用

中英文混排时的最佳化状态

  汉字(以下中文字称呼)以及受其影响的日文.韩文有一个很大的特色,就是其文字的造型为方块形的文字基本元素.也因为如此,中文在书写的时候会有直书以及横书两种书写应用方式. 相信大家阅读过直行排版的中文书籍,直书是中文字最传统的排版方式,中文字从发展以来一直到毛笔书写.篆刻.一直到活字印刷,直式编排一直都是中文字特有的编排方式. 而在中文传统的匾额.春联上的横式缩写.其实是一字一行的直写编排,因此其书写方向亦为由右至左的书写方式,知道这点以后,下次记得别再买到横批为由左至右书写印刷春联啦. 正由于

中英文混排-Textview重写后ellipsize属性失效

问题描述 Textview重写后ellipsize属性失效 最近遇到textview内容中英文符号混排,重写自定义textview绘制后不会提前换行了,但是不显示全部省略号ellipsize属性不起作用,不管是xml还是代码写都看不见省略号了,希望有经验的人能给出更好地解决办法 解决方案 省略号也要自己绘制,所以你要改写你的自定义组件,判断文字宽度是否快达到右侧边缘了,然后加上省略号 解决方案二: TextView中ellipsize属性TextView中ellipsize属性TextView中

js汉字排序问题 支持中英文混排,兼容各浏览器,包括CHROME_javascript技巧

具体技术 1.使用GB编码与UNICODE的转换 2.数组关联排序 注意:GB编码 库地址 http://demo.jb51.net/jslib/qswhGB2312.js 代码(demo写的很简陋) 复制代码 代码如下: <script> //power by 毛绒猫猫 liuyutong@baidu.com var strGB="啊阿埃挨哎唉哀皑癌蔼矮艾碍爱隘鞍氨安俺按暗岸胺案肮昂盎凹敖熬翱袄傲奥懊澳芭捌扒叭吧笆八疤巴拔跋靶把耙坝霸罢爸白柏百摆佰败拜稗斑班搬 扳般颁板版扮拌伴瓣半

字符串处理:中英文混排固定长度截取问题

/// <summary>    /// 从包含中英文的字符串中截取固定长度的一段,strInput为传入字符串,intLen为截取长度(一个汉字占两个位).    /// </summary>    public string cutString(string strInput,int intLen)    {     strInput=strInput.Trim();     byte[] myByte = System.Text.Encoding.Default.GetByt