今晚在写框架的表单验证类时,需要判断某个字符串长度是否在指定区间内,很自然地,想到了PHP中的strlen函数。

  1. $str = 'Hello world!';
  2. echo strlen($str);  // 输出12

然而在PHP自带的函数中,strlen及mb_strlen都是通过计算字符串所占字节数来计算长度的,在不同的编码情况下,中文所占的字节数是不同的。在GBK/GB2312下,中文字符占2个字节,而在UTF-8下,中文字符占3个字节。

  1. $str = '你好,世界!';
  2. echo strlen($str);  // GBK或GB2312下输出12,UTF-8下输出18

而我们在判断字符串长度时往往需要判断的是字符的数量,而非字符串所占字节数,如在UTF-8下的这段PHP代码:

  1. $name = '张耕畅';
  2. $len = strlen($name);
  3. // 输出 FALSE,因为在UTF-8下三个中文占9个字节
  4. if($len >= 3 && $len <= 8){
  5. echo 'TRUE';
  6. }else{
  7. echo 'FALSE';
  8. }

那么有什么方便而实用的方法可以获得含中文字符串的长度呢?可以用正则计算出中文字符的个数,在GBK/GB2312编码下除以2,UTF-8编码下则除以3,最后再加上非中文字符串的长度,但这样未免太过麻烦。

WordPress这么一段代码,借鉴如下:

  1. $str = 'Hello,世界!';
  2. preg_match_all('/./us', $str, $match);
  3. echo count($match[0]);  // 输出9

思想是用正则表达式将字符串分割成单个字符,并直接用count计算出匹配到的字符数,便是我们想要的结果了。

但以上代码在UTF-8编码下并不能处理GBK/GB2312的中文字符串,因为GBK/GB2312的中文字符会被识别为两个字符而计算出来的中文字符数量会翻倍,于是我想到了这么一个办法:

  1. $tmp = @iconv('gbk', 'utf-8', $str);
  2. if(!empty($tmp)){
  3. $str = $tmp;
  4. }
  5. preg_match_all('/./us', $str, $match);
  6. echo count($match[0]);

可兼容GBK/GB2312及UTF-8编码,经小量数据测试通过,但暂未确定是否完全正确,盼有大牛指点一二。

以上本意是为了框架可以兼容多种编码格式,但一般在日常开发中,一个项目是已经可以确定为何种编码的,因此可以使用以下函数来方便地获取字符串长度:

  1. int iconv_strlen ( string $str [, string $charset = ini_get("iconv.internal_encoding") ] )

PHP中获取中英文混合字符串长度[主要是指个数,而不是字符串长度](转)的更多相关文章

  1. PHP获取中英文混合字符串长度及截取

    1.字符串长度 PHP获取中英文混合字符串长度的实现代码如下,1中文=1位,2英文=1位,可自行修改 /** * PHP获取字符串中英文混合长度 * @param $str string 字符串 *  ...

  2. 如何让JS变量和字符串拼接后,是变量而不是字符串

    今天有个非常有趣的事,因为我需要用JS去实现多语言,就是我在JS文件里定义了不同的变量,尝试用变量拼接字符串组成之前定义好的变量名称,结果拼接之后,显示的却是字符串,而不是变量,所以无法解析 zh_t ...

  3. PHP 获取中英文混合字符串长度

    通常情况下要想掌握一个字符串变量的长度[一般掌握其字数],自然想到 strlen |--   $str = 'string'; echo strlen($str); //6 .csharpcode, ...

  4. Python统计字符串中的中英文字符、数字空格,特殊字符

    # -*- coding:utf8 -*- import string from collections import namedtuple def str_count(s): '''找出字符串中的中 ...

  5. elasticsearch的store属性跟_source字段——如果你的文档长度很长,存储了_source,从_source中获取field的代价很大,你可以显式的将某些field的store属性设置为yes,否则设置为no

    转自:http://kangrui.iteye.com/blog/2262860 众所周知_source字段存储的是索引的原始内容,那store属性的设置是为何呢?es为什么要把store的默认取值设 ...

  6. Java代码中获取Json的key值

    测试json字符串: {"access_token":"hkbQl5o_l67dZ7_vJRATKBwTLk9Yj5QyMuOJThAr8Baj0xWf4wxW1p4ym ...

  7. 数组中重复的数字 牛客网 剑指Offer

    数组中重复的数字 牛客网 剑指Offer 题目描述 在一个长度为n的数组里的所有数字都在0到n-1的范围内. 数组中某些数字是重复的,但不知道有几个数字是重复的.也不知道每个数字重复几次.请找出数组中 ...

  8. C#与JS实现 获取指定字节长度 中英文混合字符串 的方法

    平时在作数据库插入操作时,如果用 INSERT 语句向一个varchar型字段插入内容时,有时会因为插入的内容长度超出规定的长度而报错. 尤其是插入中英文混合字符串时,SQL Server中一般中文要 ...

  9. ThinkPHP+Smarty模板中截取包含中英文混合的字符串乱码的解决方案

    好几天没写博客了,其实有好多需要总结的,因为最近一直在忙着做项目,但是困惑了几天的Smarty模板中截取包含中英文混合的字符串乱码的问题,终于解决了,所以记录下来,需要的朋友看一下: 出现乱码的原因: ...

随机推荐

  1. PHPUNIT 单元测试

    在windows上的安装可以参考其手册 首先下载phpunit.phar文件 1. 为php的二进制可执行文件建立 一个目录,如C:\bin 2. 将C:\bin添加到系统环境变量中, 3. 打开命令 ...

  2. 利用icepdf将pdf文件转为图片

    所需jar 包为icepdf-core.jar.icepdf-extra.jar.icepdf-pro-intl.jar.icepdf-pro.jar和icepdf-viewer.jar. 示例代码如 ...

  3. ARCGIS10如何修改图例的大小

    设置好图例的样式,然后转换成图形,接着ungroup,全部打散,就可以对每一个图形包括文字进行大小和格式的编辑

  4. [转]ASP.NET MVC Jquery Validate 表单验证的多种方式介绍

    在我们日常开发过程中,前端的表单验证很重要,如果这块处理不当,会出现很多bug .但是如果处理的好,不仅bug会很少,用户体验也会得到很大的提升.在开发过程中我们可以不借助 JS 库,自己去手写 JS ...

  5. MongoDB之二基础入门(安装启动)

    mongodb中有三元素:数据库,集合,文档,其中“集合” 就是对应关系数据库中的“表”,“文档”对应“行”. 一. 下载 上MongoDB官网 ,我们发现有32bit和64bit,这个就要看你系统了 ...

  6. iOS7程序后台运行

    介绍 这次 iOS7 对程序后台运行进行了加强,但是仅仅是加强而已,要想像 Android 程序那样自由当然就别想了,苹果这么做主要还是出于电池使用时间考虑,但是这次的加强对大部分程序基本够用. 在介 ...

  7. MSP430主系统时钟以及430的低功耗设置

    如何将系统时钟设置到外部高频晶体振荡器,430的MCLK默认的是DCO的,如何安全的从DCO切换到外部晶体振荡器,这是一个很重要的步骤,因为经过此步骤,可以极大地提高430的处理能力,DCO在内部,可 ...

  8. sql-定义变量

    declare @subject nvarchar(50) set @subject=(select Subject from dbo.Scores where ID=1) --select @sub ...

  9. POJ-3744 Scout YYF I 概率DP

    题目链接:http://poj.org/problem?id=3744 简单的概率DP,分段处理,遇到mine特殊处理.f[i]=f[i-1]*p+f[i-2]*(1-p),i!=w+1,w为mine ...

  10. OpenSSH 密钥管理:RSA/DSA 认证(转载)

    我们中有许多人把优秀的 OpenSSH用作古老的 telnet 和 rsh 命令的替代品,OpenSSH 不仅是安全的而且是加密的. OpenSSH 更加吸引人的特性之一是它能够使用基于一对互补的数字 ...