2013年01月曾答应博客园网站管理员会在博客园发布原创内容,当时还不太懂技术,一直拖到现在编出解决百度字数统计问题的专业文章。
1.1 字节
字节(B)是 Byte 的中文,多用作存储容量单位,亦可作为传输容量单位。 英文维基百科解释
The byte /ˈbaɪt/ is a unit of digital information in computing and telecommunications that most commonly consists of eight bits.
字节(读音: 百特)是计算与通信中一种数字信息单位,1 字节代表 8 比特最常见。
1 字节(Byte) = 1 个英文字符(UTF-8 编码) = 8 比特(bit) = 8 位二进制数字
1.2 百度计算中文长度验证
汉语字符不同于英语字符,有 3 种常见长度,分别是 2, 3, 4 字节。
案例 1
百度搜索结果URL参数解析疑问 - 搜外问答<?php echo strlen('百度搜索结果URL参数解析疑问 - 搜外问答');?>中文 16 个字符
非中文 6 字节
PHP strlen() 函数
华文 = (54 - 6) / 16 = 3 字节
改·字数统计函数
华文 = (38 - 6) / 16 = 2 字节
1.3 百度字数统计函数与计算搜索结果标题为同一函数
案例 2
Рослинництво, тваринництвотавет...
百度改·字数统计函数 63 字节
正则表达式 45 字节
PHP strlen + mb_strlen 函数 48.5 字节
截图中上方标题约为下方标题长度一半,都触发截断,只有改·字数统计函数的计算结果与前述标题字节上限结论一致。 其他 2 种字数统计能解释标题长度为何较短,但与触发标题字节上限误差较大。
1.4 速度测试
★★☆☆☆ 2 星 改·字数统计函数采用 for 循环遍历每个字符,速度较慢,适合少量计算。
★★★☆☆ 3 星 正则表达式处理较短单一字符集有优势。
★★★★★ 5 星 PHP strlen + mb_strlen 函数的优点是无论多少字数,速度快捷稳定。
1.5 兼容性测试
案例 3
···(3 个间隔号)
改·字数统计函数 6 字节
正则表达式 4 字节
PHP strlen + mb_strlen 函数 4.5 字节
вуліца(白俄罗斯)
改·字数统计函数 12 字节
正则表达式 8 字节
PHP strlen + mb_strlen 函数 9 字节
★★★★★ 5 星 论文主要用解释百度标题计数,改·字数统计函数兼容性自是最好。
★★★☆☆ 3 星 正则表达式缺陷在于小范围的字符集内有效,超出中英文字符等集合便失效了。
★★★☆☆ 3 星 当然 PHP 自带函数兼容性比正则表达式好不到哪里。
1.6 速度与兼容性最优化方案
最少限制与应用范围考虑,百度搜索结果基本属于中英文符号混杂 64 字节以内标题为主,使用百度的改·字数统计函数最合适。
1.7 字数统计工具结果比较
案例 4
拿乌克兰语网站测试各个字数统计工具算法差异
Рослинництво, тваринництво та ветеринарія, технічне забезпечення :: Аграрний сектор України 动植物与兽医学,技术支持: 乌克兰农村经济
微软 word2010 10 字数
站长工具 66 字符
爱站网 91 字符
正则表达式 123 字节
PHP strlen + mb_strlen 函数 130 字节
搜外 163 字节
排版助手 166 字节
有一个网站 169 字节
百度改·字数统计函数 169 字节
站长工具、爱站网、九九参考计算网、工具猫、xpcha、正则表达式、PHP 函数等字数统计结果与百度计算方式相去较远。
搜外seo综合诊断较为接近百度字数统计结果,缺点是运行耗时长及受限于只能查询指定域名,使用范围不大。
排版助手作为网络编辑常用的工具,很接近百度计算方式,很实用,不过仍有误差。
有一个网站在线字数统计与百度改·字数统计函数计算结果一致,不过在间隔号、回车等符号计算方法与之不同。
1.8 PHP 源码
百度改·字数统计函数
<?php $str = stripslashes(htmlspecialchars_decode($words, ENT_QUOTES)); function smarty_modifier_wordcount($str,$encoding = 'UTF-8') { if(strtolower($encoding) == 'gbk') { $encoding = 'gb18030'; } if(!is_string($str)||$str === '') return false; $mbLen = iconv_strlen($str, $encoding); $subLen = 0; for ($i = 0; $i < $mbLen; $i++) { $mbChr = iconv_substr($str, $i, 1, $encoding); if (1 == strlen($mbChr)) { $subLen += 1; } else { $subLen += 2; } } return $subLen; } echo smarty_modifier_wordcount($str); ?>
正则表达式
<?php $str = stripslashes(htmlspecialchars_decode($words, ENT_QUOTES)); $number += strlen(preg_replace('/[\x80-\xff]{1,3}/', ' ', $str, -1, $number)); echo $number; ?>
PHP strlen + mb_strlen 函数
<?php $str = stripslashes(htmlspecialchars_decode($words, ENT_QUOTES)); echo ((strlen($str) + mb_strlen($str, 'UTF8')) / 2); ?>
参考资料
百度改·字数统计函数代码