如何将包含表情符号的字符串拆分为数组?
Posted
技术标签:
【中文标题】如何将包含表情符号的字符串拆分为数组?【英文标题】:How can I split a string containing emoji into an array? 【发布时间】:2014-08-23 06:45:38 【问题描述】:(您需要 Firefox 或 Safari 才能看到代码中的表情符号。)
我想用一串表情符号对单个字符做一些事情。
在 javascript 中 "????????????⛔????????????".length == 13
因为 "⛔"
长度为 1,其余为 2。所以我们不能这样做
var string = "????????????⛔????????????";
s = string.split("");
c = [];
c[0] = s[0]+s[1];
console.log(c);
【问题讨论】:
mathiasbynens.be/notes/… 【参考方案1】:Orlin Georgiev 的 Grapheme Splitter 库非常棒。
虽然有一段时间没有更新,目前(2020 年 9 月)它只支持 Unicode 10 及以下。
有关支持 Unicode 13 的 Typescript 中内置的 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 的最新版本,因为原始库没有更新了几年,似乎不再维护。
【讨论】:
【参考方案2】:可以使用正则表达式的u
标志来完成。正则表达式为:
/.*?/u
每次至少有零个或多个字符可能是也可能不是表情符号,但不能是空格或换行符时,这就会被打破。
至少有零个或多个:?
(分成零个字符)
零个或多个:*
不能是空格或换行符:.
可能是也可能不是表情符号:/u
通过使用问号?
,我强制删除每个零字符,否则/.*/u
它会删除所有字符,直到找到空格或换行符为止。
var string = "???⛔???"
var c = string.split(/.*?/u)
console.log(c)
【讨论】:
'??'.split(/.*?/u); // [ "?", "?" ]
【参考方案3】:
现代/正确的分割 UTF8 字符串的方法是使用 Array.from(str)
而不是 str.split('')
【讨论】:
这太棒了。通过他们,MDN 也为此提供了一个 polyfill。见:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 遗憾的是,这与复合的效果不一样:Array.from('????'); // [ "?", "", "?", "", "?", "", "?" ]
Array.from('??'); // [ "?", "?" ]
【参考方案4】:
编辑:请参阅 Orlin Georgiev's answer 以获取库中的适当解决方案:https://github.com/orling/grapheme-splitter
感谢this answer 我做了一个函数,它接受一个字符串并返回一个表情符号数组:
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 [ "?", "?", "?", "⛔", "?", "?", "?" ]
【讨论】:
请注意,这不适用于使用零宽度连接符、变体选择器或键帽表情符号(数字 + 键帽 + 变体选择器)的表情符号 只要使用match
方法str.match(/([\uD800-\uDBFF][\uDC00-\uDFFF])/);
,它就会返回表情符号
我试过你的函数,它对我有用,但看看这个:emojiStringToArray("???⛔???❤️❤️❤️❤️❤️❤️") // => Array [ "?" , "?", "?", "⛔", "?", "?", "?", "❤️❤️❤️❤️❤️❤️" ] 你知道如何解决这个错误吗?
emojiStringToArray( '????' ) // ["?", "", "?", "", "?", "", "?"]
【参考方案5】:
JavaScript ES6 有一个解决方案!,对于 真正的 拆分:
[..."???⛔???"] // ["?", "?", "?", "⛔", "?", "?", "?"]
是吗?除了当您通过转译器运行它时,它可能不起作用(参见@brainkim 的评论)。只有在兼容 ES6 的浏览器上本地运行时,它才有效。幸运的是,这涵盖了大多数浏览器(Safari、Chrome、FF),但如果您正在寻找高浏览器兼容性,这不是您的解决方案。
【讨论】:
带有 es6 设置的 Babel 会将其转译为对 String 的迭代器函数的调用,因此它确实可以在某些转译器中工作。 @brainkim 我在答案中指定了这一点。不符合这个标准是转译器的错 啊,我是说它有时有效。 “当你通过你的转译器运行它时,它不会工作”意味着它永远不会工作。这取决于字符串中的特定表情符号、您使用的转译器等。[...'????'] // ["?", "", "?", "", "?", "", "?"]
[..."??"] // ["?", "?"]
【参考方案6】:
做到这一点的grapheme-splitter库,即使与旧浏览器也完全兼容,不仅适用于表情符号,还适用于各种奇特的字符: https://github.com/orling/grapheme-splitter 您可能会错过任何自制解决方案中的边缘案例。这个实际上是基于 UAX-29 Unicode 标准
【讨论】:
以上是关于如何将包含表情符号的字符串拆分为数组?的主要内容,如果未能解决你的问题,请参考以下文章