js 将字符串分割成数组时emoji表情被分割成了乱码的解决办法
直接看图吧
直接使用索引:
使用split:
使用charAt:
解决办法
// 文本分割
const splitGraphemes = (input) => {
    if (typeof Intl !== 'undefined' && Intl.Segmenter) {
        const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
        return Array.from(segmenter.segment(input), (segment) => segment.segment);
    } else {
        // 回退到正则分割
        const graphemeRegex = /(?:\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\u200D\p{Extended_Pictographic})*|[\s\S])/gu;
        return [...input.matchAll(graphemeRegex)].map(match => match[0]);
    }
}解释
Intl.Segmenter 是一个国际化 API,用于根据语言环境和特定的粒度分割字符串。
- 这里判断当前环境是否支持 Intl.Segmenter:- 如果支持,创建一个 Segmenter实例:const segmenter = new Intl.Segmenter('en', { granularity: 'grapheme' });
- 'en':指定语言环境为英文(但由于- grapheme是独立于语言的,因此适用于多种语言)。
- { granularity: 'grapheme' }:指定粒度为字素(- grapheme),即按人类可见的字符进行分割。
- 然后通过 Array.from遍历segmenter.segment(input)返回的迭代器,将每个segment对象的segment属性提取到数组中。
 
- 如果支持,创建一个 
如果 Intl.Segmenter 不可用,则使用正则表达式进行分割:
const graphemeRegex = /(?:\p{Extended_Pictographic}(?:\p{Emoji_Modifier}|\u200D\p{Extended_Pictographic})*|[\s\S])/gu;
return [...input.matchAll(graphemeRegex)].map(match => match[0]);- \p{Extended_Pictographic}:匹配扩展图形字符(主要是表情符号和特殊符号)。
- (?:...):非捕获组,用于将匹配的表情符号与修饰符或零宽连接符(- u200D)组合起来。
- [\s\S]:匹配所有其他字符(如果不是表情符号)。
- /gu:- g:全局匹配,匹配所有字素。
- u:启用 Unicode 模式,确保正确处理 Unicode 字符。
 
步骤:
- 使用 input.matchAll(graphemeRegex)获取所有匹配的字素。
- 将每个匹配的结果提取为一个字符串并返回为数组。
- Intl.Segmenter是更现代、准确的方式,尤其适用于需要国际化支持的环境。
- 如果 Intl.Segmenter不可用,则使用正则表达式作为兼容方案。
适用场景:
- 处理用户输入中的 Emoji 或复合字符。
- 文本编辑器、聊天应用等需要逐字素处理的应用。



