Как я могу разбить строку, содержащую эмодзи, в массив?

(Вам понадобится Firefox или Safari, чтобы увидеть смайлики в коде.)

Я хочу взять смайлик и сделать что-то с отдельными персонажами.

В JavaScript "⛔".length == 13 так как "⛔" длина 1, остальные 2. Так что мы не можем сделать

s = string.split(""); 
c = [];
c[0] = s[0]+s[1];

Вот что я сделал: плакат эмодзи

7 ответов

Решение

Библиотека графит-сплиттера, которая делает именно это, полностью совместима даже со старыми браузерами и работает не только с эмодзи, но и со всеми видами экзотических символов: https://github.com/orling/grapheme-splitter случаи в любом домашнем растворе. Этот на самом деле основан на стандарте Unixode UAX-29

У JavaScript ES6 есть решение!, для реального раскола:

[..."⛔"] // ["", "", "", "⛔", "", "", ""]

Ура? За исключением того факта, что когда вы запускаете это через транспортер, это может не сработать (см. Комментарий @brainkim). Он работает только в том случае, если изначально работает в браузере, совместимом с ES6. К счастью, это относится к большинству браузеров (Safari, Chrome, FF), но если вы ищете высокую совместимость с браузерами, это не решение для вас.

Изменить: см . Ответ Орлина Георгиева для правильного решения в библиотеке: https://github.com/orling/grapheme-splitter


Благодаря этому ответу я сделал функцию, которая принимает строку и возвращает массив emoji:

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 [ "", "", "", "⛔", "", "", "" ]

С предстоящимIntl.Segmenter. Ты можешь это сделать:

      const splitEmoji = (string) => [...new Intl.Segmenter().segment(string)].map(x => x.segment)

splitEmoji("⛔") // ['', '', '', '⛔', '', '', '']

Это также решает проблему с «‍‍‍» и «».

      splitEmoji("‍‍‍") // ['‍‍‍', '']

Согласно CanIUse, помимо IE и Firefox, в настоящее время его можно использовать на 84,17% по всему миру .

Современный / правильный способ разбить строку UTF8 - использовать Array.from(str) вместо того str.split('')

Библиотека Grapheme Splitter Орлина Георгиева просто потрясающая.

Хотя он не обновлялся некоторое время и в настоящее время (сентябрь 2020 г.), он поддерживает только Unicode 10 и ниже.

Для обновленной версии Grapheme Splitter, встроенной в Typescript с поддержкой Unicode 13, посмотрите: 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)

Другие вопросы по тегам