一起养成写作习惯!这是我参与「掘金日新计划 · 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)
}
//=> '👨'
//=> ''
//=> '👩'
//=> ''
//=> '👧'
//=> ''
//=> '👦'
注意:
- 空字符串的 length 为 0。
- 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].length | Intl.Segmenter |
---|---|---|---|
三个字 | 3 | 3 | 3 |
three | 5 | 5 | 5 |
🙃 | 2 | 1 | 1 |
👨👩👧👦 | 11 | 7 | 1 |