我想获取一串表情符号并对各个字符进行一些操作。
在JavaScript中
"😴😄😃⛔🎠🚓🚇".length == 13
因为"⛔"
长度为1,其余都是2。所以我们不能这样做
var string = "😴😄😃⛔🎠🚓🚇";
s = string.split("");
console.log(s);
JavaScript ES6 有一个解决方案!,用于 real 分割:
[..."😴😄😃⛔🎠🚓🚇"] // ["😴", "😄", "😃", "⛔", "🎠", "🚓", "🚇"]
是吗?除了当您通过转译器运行它时,它可能不起作用(请参阅@brainkim的评论)。它仅在本地运行于 ES6 兼容浏览器上时才有效。幸运的是,这涵盖了大多数浏览器(Safari、Chrome、FF),但如果您正在寻找高浏览器兼容性,这不是您的解决方案。
Intl.Segmenter
。你可以这样做:
const splitEmoji = (string) => [...new Intl.Segmenter().segment(string)].map(x => x.segment)
splitEmoji("😴😄😃⛔🎠🚓🚇") // ['😴', '😄', '😃', '⛔', '🎠', '🚓', '🚇']
这也解决了“👨u200d👨u200d👧u200d👧”和“👦🏾”的问题。
splitEmoji("👨👨👧👧👦🏾") // ['👨👨👧👧', '👦🏾']
根据 CanIUse,所有现代浏览器都支持此功能。
如果您需要支持较旧的浏览器,如Matt Davies的回答中提到的,Graphemer是最好的解决方案:
let Graphemer = await import("https://cdn.jsdelivr.net/npm/[email protected]/+esm").then(m => m.default.default);
let splitter = new Graphemer();
let graphemes = splitter.splitGraphemes("👨👨👧👧👦🏾"); // ['👨👨👧👧', '👦🏾']
编辑:请参阅 Orlin Georgiev 的答案,了解库中的正确解决方案:https://github.com/orling/grapheme-splitter
感谢这个答案我做了一个函数,它接受一个字符串并返回一个表情符号数组:
var emojiStringToArray = function (str) {
split = str.split(/([\uD800-\uDBFF][\uDC00-\uDFFF])/);
arr = [];
for (var i=0; i<split.length; i++) {
char = split[i]
if (char !== "") {
arr.push(char);
}
}
return arr;
};
那么
emojiStringToArray("😴😄😃⛔🎠🚓🚇")
// => Array [ "😴", "😄", "😃", "⛔", "🎠", "🚓", "🚇" ]
grapheme-splitter 库就可以做到这一点,甚至与旧浏览器完全兼容,并且不仅适用于表情符号,还适用于各种外来字符: https://github.com/orling/grapheme-splitter 您可能会错过任何自制解决方案中的边缘情况。这个实际上是基于 UAX-29 Unicode 标准
分割 UTF8 字符串的现代/正确方法是使用
Array.from(str)
而不是 str.split('')
Orlin Georgiev 的 Grapheme Splitter 库非常棒。
虽然它已经有一段时间没有更新了,目前(2020 年 9 月)它仅支持 Unicode 10 及以下版本。有关在 Typescript 中内置且支持 Unicode 13 的 Grapheme Splitter 的更新版本,请查看:
https://github.com/flmnt/graphemer
这是一个简单的例子:
import Graphemer from 'graphemer';
const splitter = new Graphemer();
const string = "😴😄😃⛔🎠🚓🚇";
splitter.countGraphemes(string); // returns 7
splitter.splitGraphemes(string); // returns array of characters
该库还支持最新的表情符号。例如
"👩🏻🦰".length === 7
但是
splitter.countGraphemes("👩🏻🦰") === 1
。完全披露:我创建了该库并完成了更新到 Unicode 13 的工作。该 API 与 Grapheme Splitter 相同,并且完全基于该工作,只是更新到了 Unicode 的最新版本,因为原始库尚未更新已经有几年了,似乎不再维护了。
u
标志来完成。正则表达式为:
/.*?/u
每次至少有零个或多个字符可能是也可能不是表情符号,但不能是空格或换行符时,就会被破坏。
?
(分成零个字符)
*
.
/u
?
我强制精确地剪切每个零字符,否则
/.*/u
它会剪切所有字符,直到找到空格或换行符。
var string = "😴😄😃⛔🎠🚓🚇"
var c = string.split(/.*?/u)
console.log(c)