Страницы

Поиск по вопросам

среда, 26 февраля 2020 г.

? вместо эмодзи

#javascript #google_apps_script


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

  var contents = JSON.parse(e.postData.contents);
  var text = contents.message.text
  var textar = text.split("");
  var sheet = SpreadsheetApp.openById(ssId);
  sheet.getSheetByName(sheetName).appendRow([text,textar[4]]);


Таким образом мне приходит оригинальный текст + конкретный символ(на котором обязательно
будет эмодзи). Однако в таблице появляется "?", хотя в соседней ячейке эмодзи прекрасно
отображается в рамках всего сообщения.
Как изменить код, чтобы скрипт верно отправлял на запись именно эмодзи и не терял его?
    


Ответы

Ответ 1



text.split(""); правильно разбивает только те строки, которые состоят из юникод-символов, закодированных двумя байтами в кодировке UTF-16 (code unit). Эмодзи, как правило, кодируются четырмя байтами (2 code units), поэтому разбиваются на две части так называемой суррогатной пары, каждая из которых не может быть самостоятельным символом и представляется знаком вопроса при отображении. Правильная разбивка может быть сделана при помощи [...text] выражения, так как в современном JavaScript строка поддерживает протокол итерации, который разбивает её на символы, независимые от кодировки (code points). Поэтому попробуйте: var textar = [...text]; Подробнее можно почитать: The Absolute Minimum Every Software Developer Absolutely, Positively Must Know About Unicode and Character Sets (No Excuses!) – Joel on Software What every JavaScript developer should know about Unicode JavaScript has a Unicode problem · Mathias Bynens Unicode-aware regular expressions in ES2015 · Mathias Bynens ES6 Strings (and Unicode, ❤) in Depth Jonathan New | "💩".length === 2 P.S. Если вы ограничены использованием ES5, можно попробовать комбинацию из полифилов String.prototype.codePointAt() + String.fromCodePoint() по сылкам (т.е. text.split("")[4] заменить на String.fromCodePoint(text.codePointAt(4))).

Комментариев нет:

Отправить комментарий