如何将包含表情符号的字符串拆分为数组?

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 === 7splitter.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 标准

【讨论】:

以上是关于如何将包含表情符号的字符串拆分为数组?的主要内容,如果未能解决你的问题,请参考以下文章

PHP:将字符串拆分为数组 foreach char

如何拆分字符串但在java中保留分隔符? [复制]

如何将包含字符“\ n”的多行字符串拆分为bash中的字符串数组? [复制]

如何在awk中将分隔字符串拆分为数组?

将字符串拆分为 3d 数组

如何将字符串拆分为单词。例如:“stringintowords”->“String Into Words”?