Анализ эмодзи в Node.js

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

Я прочитал эту замечательную статью Матиаса и использую как собственные punycode для кодирования / декодирование и regenerate для генерации регулярного выражения. Я также использую EmojiData, чтобы получить свой словарь смайлов.

С учетом всего сказанного, некоторые смайлики продолжают быть надоедливыми маленькими жукерами и отказываются соответствовать. За определенные эмодзи я продолжаю получать пару кодовых баллов.

// Example of a single code point:
console.log(punycode.ucs2.decode('????'));
>> [ 128169 ]

// Example of a paired code point:
console.log(punycode.ucs2.decode('⌛️'));
>> [ 8987, 65039 ]

Матиас затрагивает это в своей статье (и приводит пример использования punycode, работающего с этим), но даже используя его пример, я получаю неверный ответ:

function countSymbols(string) {
  return punycode.ucs2.decode(string).length;
}
console.log(countSymbols('????'));
>> 1
console.log(countSymbols('⌛️'));
>> 2

Как лучше всего определить, содержит ли строка все смайлы или нет? Это сделано для проверки концепции, поэтому решение может быть настолько грубым, насколько это необходимо.

--- ОБНОВИТЬ ---

Еще немного контекста о моих надоедливых смайликах выше.

Они визуально идентичны, но на самом деле разные значения Unicode (второе из приведенного выше примера):

⌛ // \u231b

⌛️ // \u231b\ufe0f

Первый отлично работает, второй - нет. К сожалению, похоже, что iOS использует вторую версию (если вы скопируете и вставите из iMessage, вы получите вторую версию, и при получении текста от Twilio то же самое).


person thekevinscott    schedule 24.09.2015    source источник
comment
Таким образом, похоже, что объединение меток (этот дополнительный бит юникода во втором примере) - вот что здесь сбивает с толку. Я изучаю, как лучше всего избавиться от этих элементов в моей строке.   -  person thekevinscott    schedule 25.09.2015
comment
Если кто-нибудь когда-нибудь столкнется с подобным вариантом использования, я упаковал все это в модуль npm: github.com/scottlabs/ emojiExists   -  person thekevinscott    schedule 29.09.2015


Ответы (2)


U+FE0F не является объединяющим знаком, это последовательность вариантов, которая управляет отображением глифа (см. этот ответ). Удаление таких последовательностей может изменить внешний вид символа, например: _2 _ + _ 3_ (⌛︎).

Кроме того, последовательности эмодзи могут быть созданы из нескольких кодовых точек. Например, U+0032 (2) сам по себе не эмодзи, а _5 _ + _ 6_ (2⃣) или _7 _ + _ 8 _ + _ 9_ (2⃣️), но _10 _ + _ 11_ (A⃣) - нет. Полный список последовательностей эмодзи содержится в файле emoji-data.txt Консорциумом Unicode (эта информация есть в библиотеке emoji-data-js).

Чтобы проверить, содержит ли строка символы эмодзи, вам нужно будет проверить, находится ли какой-либо отдельный символ в emoji-data.txt или начинает ли подстрока для последовательности в нем.

person 一二三    schedule 24.09.2015
comment
Спасибо за вашу помощь. Теперь я сначала ищу пары кодовых точек, а затем отдельные кодовые точки, и это работает для моего варианта использования. - person thekevinscott; 29.09.2015

Если, гипотетически, вы знаете, с какими персонажами, не относящимися к смайликам, вы ожидаете столкнуться, вы можете использовать небольшую магию lodash через их модули toArray или split, которые поддерживают смайлики. Например, если вы хотите узнать, содержит ли строка буквенно-цифровые символы, вы можете написать такую ​​функцию:

function containsAlphaNumeric(string){
 return _(string).toArray().filter(function(char){
    return char.match(/[a-zA-Z0-9]/);
 }).value().length > 0 ? true : false;
}
person Evan Rusackas    schedule 06.09.2017