PHP trim函数异常行为:多字节字符被截断出现�符号
解决PHP中trim处理印地语等UTF-8多字节字符串的乱码问题
这个坑我之前踩过!你遇到的�乱码问题,本质是PHP原生的trim()函数是字节级的操作,根本不认识UTF-8的多字节字符。你在第二个参数里加了\xC2\xA0(这是UTF-8编码的非断空格),但trim()会逐字节扫描,把多字节字符的部分字节误当成要修剪的目标,直接砍掉,剩下的残缺字节没法组成有效UTF-8字符,就变成了替换符�。
比如你处理的मठ,其中ठ是UTF-8多字节字符(编码是\xE0\xA4\xA9),当trim()扫描到某个字节和你指定的修剪字节匹配时,就会直接删除,导致字符被截断,最终显示乱码。
下面给你两个靠谱的解决方案:
方案1:用mbstring扩展的多字节安全修剪函数
如果你的PHP环境开了mbstring扩展(绝大多数生产环境都默认启用),直接用mb_trim()就完事了——它是专门为多字节字符设计的:
$inputString = "आनन्द मठ"; // 修剪所有Unicode空白字符(包括普通空格、非断空格、制表符等) $trimmed = mb_trim($inputString); // 如果要自定义修剪的字符集合,记得传Unicode字符而非字节 $trimmed = mb_trim($inputString, " \t\n\r\0\x0B\u{00A0}");
这里用\u{00A0}表示非断空格(对应你之前的\xC2\xA0),mb_trim会完整识别每个多字节字符,不会乱砍字节。
方案2:正则表达式兜底(无mbstring也能用)
如果你的环境没开mbstring,用正则+u修饰符也能实现多字节安全的修剪:
$inputString = "आनन्द मठ"; // 匹配首尾的Unicode空白字符并替换为空 $trimmed = preg_replace('/^\s+|\s+$/u', '', $inputString);
正则里的\s加上u修饰符后,会匹配所有Unicode标准的空白字符,而且是按完整字符匹配,不会拆字节,完美避免乱码问题。
再啰嗦两句为啥原代码不行
原代码里的trim()把\xC2\xA0当成独立的字节来处理,但UTF-8字符是由多个字节组合而成的。当字符串末尾的多字节字符刚好包含\xC2或者\xA0这类字节时,trim()会直接删掉这个字节,导致整个字符变成无效的UTF-8序列,浏览器/终端就会用�来表示这个无效字符。
内容的提问来源于stack exchange,提问作者Harshit
相关产品推荐
相关产品推荐

