前阵子帮朋友排查个老系统,用户昵称入库后动不动就变问号方块。查了半天才发现截断逻辑有问题:那套代码图省事,拿 substr 按"长度"硬切,默认字符串长度就是字节数。ASCII 下这俩确实一回事,可 UTF-8 里一个汉字占 3 字节、一个 emoji 占 4 字节,按字节拦腰斩,汉字直接被劈成两半,落库成乱码,严重的还会触发数据库字符集报错。
最隐蔽的是这种 bug 测试阶段根本发现不了,测试数据全是字母数字,永远碰不到多字节字符。
正解其实简单:按码点或者字素簇来切,别盲信 string length。Python 切片 [] 是按码点的,JS 用 Array.from 或 Intl.Segmenter 都行。下次写截断前,先想想你的用户会不会用中文名、爱发表情包。