👨‍👩‍👧‍👦前端如何精准的计算字数?

928 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第12天,点击查看活动详情

最近一直在知乎和掘金上写文章,掘金使用的是markdown编辑器,知乎写文章时用的是富文本编辑器。对于相同的内容,往往在知乎上已经写了几千字,粘贴到掘金上只有一千不到,掘金上对于英文字符一个单词算作一个字。

比如这篇文章掘金上显示621字,知乎上有1850字。

接下来我们看下在前端如何准确的计算字数。

一个中文汉字和一个英文字符都算作一个字。例如;

"三个字" = 3
"three" = 5

使用 String.length

length属性表示一个字符串的长度,可以返回字符编码单元的数量。JavaScript使用UTF-16的编码,此编码使用一个 16 比特的编码单元来表示大部分常见的字符,使用两个代码单元表示不常用的字符。因此 length 返回值可能与字符串中实际的字符数量不相同。

var x = "Mozilla";

console.log("Mozilla 是" + x.length + "个字"); //Mozilla 是7个字

var z = "好几个字";

console.log( z.length); //4

接下来我们看一些特殊的情况:

var y = "🙃";

console.log( y.length); //2

一个非常常用的emoji表情算作2个字,你可以猜一下👨‍👩‍👧‍👦算几个字?

var z = "👨‍👩‍👧‍👦";

console.log( z.length); //11

没错,11个字那么多,是因为这个表情是由四个小图👨、👩、👧、👦拼接而成的,我们可以通过for循环将👨‍👩‍👧‍👦分解。

for (const codePoint of '👨‍👩‍👧‍👦') {
    console.log('%o', codePoint)
}
//=> '👨'
//=> '‍'
//=> '👩'
//=> '‍'
//=> '👧'
//=> '‍'
//=> '👦'

注意:

  1. 空字符串的 length 为 0。
  2. String.length 返回 1。

使用[...""].length

如果使用将字符串转为一个数组,得出的结果和上面并不相同。

console.log( [..."👨‍👩‍👧‍👦"]);// ['👨', '‍', '👩', '‍', '👧', '‍', '👦']
console.log( [..."👨‍👩‍👧‍👦"].length);// 7

console.log( [..."🙃"].length);// 1

使用 Intl.Segmenter

另外一种在 JavaScript 中计算字符数的方法是使用 Intl.Segmenter。

Intl.Segmenter 是一种 API,可以考虑到语言环境,将字符串分解为字素、单词和句子。

const segmenter = new Intl.Segmenter("zh", { granularity: "grapheme" });
console.log([...segmenter.segment("🙃")].length); // 1

const segmenter = new Intl.Segmenter("zh", { granularity: "grapheme" });
console.log([...segmenter.segment("👨‍👩‍👧‍👦")].length); // 1

可以看到,上面表情的length只有1,这也更符合我们的计算需求。

总结:

文字string.length[...string].lengthIntl.Segmenter
三个字333
three555
🙃211
👨‍👩‍👧‍👦1171