字符串长度计算(支持表情符号)

正确计算包含 emoji 和特殊 Unicode 字符的字符串长度

问题

如何正确计算字符串长度,使其支持 emoji 表情和特殊 Unicode 字符?

解答

为什么 length 不准确

JavaScript 中 str.length 返回的是 UTF-16 编码单元的数量,而不是实际字符数。对于超出基本多文种平面(BMP)的字符,会被编码为两个编码单元:

'汉'.length  // 1
'😀'.length  // 2(emoji)
'𠮷'.length  // 2(生僻汉字)

使用字符串迭代器

ES6 的字符串迭代器能正确识别 Unicode 字符边界:

const testStr = '123😀'

for (let c of testStr) {
  console.log(c)
}
// 输出:
// 1
// 2
// 3
// 😀

console.log([...testStr].length)  // 4

封装计算函数

使用 Array.from() 将字符串转换为字符数组:

function unicodeLength(str) {
  return Array.from(str).length
}

unicodeLength('123😀')  // 4
unicodeLength('𠮷汉字')  // 3

关键点

  • str.length 返回的是 UTF-16 编码单元数,不是实际字符数
  • emoji 和部分生僻字占用 2 个编码单元,导致 length 计数错误
  • 使用扩展运算符 [...str]Array.from(str) 可正确拆分字符
  • 字符串迭代器(for...of)能正确遍历 Unicode 字符