PHP中统计含HTML标签字符串的单词数异常问题
问题分析
你遇到的问题根源在于**Unicode非断空格(U+00A0)**的处理漏洞:
当你调用html_entity_decode($str)时,字符串中的 会被解码为U+00A0(而非普通空格U+0020)。但你的rip_tags函数只处理了普通空格、换行、制表符,完全忽略了这个特殊空格:
trim()默认只会去除普通空格、换行、制表符等,不会处理U+00A0,所以解码后的非断空格会残留下来。- 你用来合并多个空格的正则
/ {2,}/只匹配普通空格,对U+00A0无效,导致非断空格仍然留在字符串中。 str_word_count()默认不把U+00A0视为单词分隔符,但它本身也不是单词字符,这就导致函数错误地将非断空格前后的内容计数为独立的“单词”,最终得到了不符合预期的结果。
解决方案
只需在rip_tags函数中添加一行代码,将U+00A0替换为普通空格,之后再进行空格合并和trim操作即可:
function rip_tags($string) { // ----- 移除HTML标签 ----- $string = preg_replace ('/<[^>]*>/', ' ', $string); // ----- 将非断空格替换为普通空格 ----- $string = str_replace("\xA0", ' ', $string); // ----- 移除控制字符 ----- $string = str_replace("\r", '', $string); $string = str_replace("\n", ' ', $string); $string = str_replace("\t", ' ', $string); // ----- 合并多个空格 ----- $string = trim(preg_replace('/ {2,}/', ' ', $string)); return $string; } $str = '<p>&nbsp;<p>hello world!</p><p>&nbsp;</p></p>'; $str = html_entity_decode($str); // 提前trim可以省略,因为rip_tags最后会做trim $str = rip_tags($str); $c = str_word_count($str); echo $c; // 现在会输出预期的2
额外优化提示
- 你可以把
html_entity_decode的结果直接传入rip_tags,不需要提前调用trim(),因为rip_tags最后已经做了trim操作,避免重复处理。 - 如果需要处理更多Unicode空白字符(比如全角空格),可以用正则
/\s+/u来匹配所有空白字符并替换为单个普通空格,兼容性更好:$string = preg_replace('/\s+/u', ' ', $string);
内容的提问来源于stack exchange,提问作者dapidmini
相关产品推荐
相关产品推荐

