在通常情况下,对于
let str = 'abcd';
有str.length = 4
。
但是,若
str = '👨👩👧👦👵🏻';
此时有str.length = 15
,仅仅 2 字符就占了 15 个常规字符位。这是由于单个 Emoji 等字符拥有两个及以上的常规字符位造成的。
此时用indexOf()
等函数无法确切定位到字符串中的字符位置。
为什么有 Emoji 字符占用多的这种问题?如果你感兴趣,可以拉到文章末尾,我先介绍解决方案。
方案一 使用工具处理
我们这里使用开源项目orling/grapheme-splitter处理。
下载仓库内的 index.js,引入网页等。
var splitter = new GraphemeSplitter();
var graphemes = splitter.splitGraphemes(string);
这样得到的graphemes
就是目标字符串(数组)。
graphemes = ['👨👩👧👦','👵🏻']
方案二 手工分组
str = ['👨👩👧👦','👵🏻'];
问题来源
这是由于复杂的 Emoji 符号由基础 Emoji 符号拼凑而成。
例如,符号“👨👩👧👦”由 15 字符组成,分别是:
- 👨 男人(Man)2 字符
- 零宽连字(Zero Width Joiner, ZWJ)
- 👩 女人(Woman)2 字符
- 零宽连字(Zero Width Joiner, ZWJ)
- 👧 女孩(Girl)2 字符
- 零宽连字(Zero Width Joiner, ZWJ)
- 👦 男孩(Boy)2 字符
在这个符号里,ZWJ 符号把四个基础的表情符号联系到一起,组成新的字符。
又比如符号“👵🏻”由 4 字符组成,分别是:
- 👵 老奶奶(Old Woman)2 字符
- 零宽连字(Zero Width Joiner, ZWJ)
- 🏻 浅肤色(Light Skin Tone)1 字符
所以,依靠charAt()
无法准确地逐字输出他们。