【问题标题】: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);

【问题讨论】:

标签: javascript unicode emoji


【解决方案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('')

    【讨论】:

    【解决方案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 标准

    【讨论】:

      猜你喜欢
      • 2020-04-06
      • 1970-01-01
      • 1970-01-01
      • 2016-01-12
      • 2021-04-05
      • 2010-12-25
      • 2021-10-25
      • 1970-01-01
      • 2020-10-19
      相关资源
      最近更新 更多