Я хочу получить определенные буквы из строки юникода, используя index. Однако это не работает так, как ожидалось.
Пример:
var handwriting = `????????????????????????????????????????????????????1234567890`
var normal = `abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890`
console.info(normal[3]) // gives 'd' but
console.info(handwriting[3]) // gives '�' instead of '?'
также длина не работает должным образом normal.length
дает правильное значение как 62, но handwriting.length
дает 114.
Индексация не работает должным образом. Как я могу получить доступ к элементам массива Unicode?
Я пробовал это на питоне, он отлично работает, но в Javascript он не работает.
Мне нужны точные символы из строки юникода, такие как ожидаемый вывод «d» «?» для индекса 3
Связано: thekevinscott.com/emojis-in-javascript
@phuzi выбирает персонажей здесь настоящая проблема.
Примечание: это не почерк (это математическая запись), и не следует использовать Unicode для форматирования: вы создадите гораздо больше проблем. Юникод — это семантика. Используйте шрифты (и разметку) для форматирования. Вы можете использовать стандартную декомпозицию Unicode, чтобы перейти от математики к буквам (что гораздо более обобщенно).
In Javascript, a string is a sequence of 16-bit code points. Since these characters are encoded above the Basic Multilingual Plane, it means that they are represented by a pair of code points, also known as a surrogate pair.
Юникодный номер ?
— U+1D586
. И 0x1D586 больше, чем 0xFFFF (2^16). Итак, ?
представлен парой кодовых точек, также известной как суррогатная пара.
console.info("?".length)
console.info("?" === "\uD835\uDD86")
Один из способов — создать массив символов, используя синтаксис распространения или Array.from()
, а затем получить нужный индекс.
var handwriting = `????????????????????????????????????????????????????1234567890`
console.info([...handwriting][3])
console.info(Array.from(handwriting)[3])
… пока это не произойдет. Попробуйте [...'?❤️??'].length
, и выражение вернет 8 вместо 1, как ожидает человек. Распределяйте количество символов, а не графем, см. <stackoverflow.com/a/51422499/46395>. Я бы хотел, чтобы язык и его разработчики серьезно относились к Unicode, но они этого не делают, поэтому программисты должны страдать.
@daxim хорошо замечен. Чем больше я читаю про юникод, тем больше запутываюсь. Если я вставлю приведенную выше строку с эмодзи в консоль, я увижу \u200D
пустое место. Это часть смайлика? Почему у каждого эмодзи по 3 кодовых точки?
@adiga - Это не просто смайлики, все, что связано с метками, имеет ту же проблему. Например, [..."Français"][4]
— это c
(потому что я написал это с c
, за которым следует комбинированный знак для седиля, а не с использованием комбинированного символа ç
). Это... не очень весело. :-D normalize
может помочь в таких случаях, когда есть эквивалент одного символа, но часто его нет.
Символ Юникода выглядит как «\ u00E9», поэтому, если ваша строка длиннее, это нормально. Чтобы иметь реальную длину строки Unicode, вы должны преобразовать ее в массив:
let charArray = [...handwriting]
console.info(charArray.length) //=62
Каждый элемент вашего массива является символом вашей строки. charArray[3] вернет вам символ Юникода, соответствующий «?»
Как вы уже обнаружили, символы Юникода редко состоят из одного байта. Вам понадобится какой-то способ анализа байтов Unicode и выбора из них «символов».