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;
}