Node.js Emoji Парсинг

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

Я прочитал эту замечательную статью Матиаса и использую оба 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

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

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

Немного больше контекста о моих надоедливых смайликах выше.

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

⌛ // \u231b

⌛️ // \u231b\ufe0f

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

2 ответа

Решение

U+FE0F это не комбинационная метка, это вариационная последовательность, которая контролирует рендеринг глифа (см. этот ответ). Удаление таких последовательностей может изменить внешний вид персонажа, например: U+231B+U+FE0E (⌛︎).

Кроме того, последовательности эмодзи могут быть сделаны из нескольких кодов. Например, U+0032 (2) сам по себе не смайлик, но U+0032+U+20E3 (2⃣) или U+0032+U+20E3+U+FE0F (2⃣️) - но U+0041+U+20E3 (A⃣) нет. Полный список последовательностей смайликов поддерживается в файле emoji-data.txt Консорциумом Юникод (emoji-data-js библиотека, кажется, имеет эту информацию).

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

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

function containsAlphaNumeric(string){
 return _(string).toArray().filter(function(char){
    return char.match(/[a-zA-Z0-9]/);
 }).value().length > 0 ? true : false;
}
Другие вопросы по тегам