Как получить правильный элемент из строки юникода?

Я хочу получить определенные буквы из строки юникода, используя 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

Как вы уже обнаружили, символы Юникода редко состоят из одного байта. Вам понадобится какой-то способ анализа байтов Unicode и выбора из них «символов».

phuzi 31.05.2019 09:11

Связано: thekevinscott.com/emojis-in-javascript

adiga 31.05.2019 09:13

@phuzi выбирает персонажей здесь настоящая проблема.

AzizStark 31.05.2019 09:15

Примечание: это не почерк (это математическая запись), и не следует использовать Unicode для форматирования: вы создадите гораздо больше проблем. Юникод — это семантика. Используйте шрифты (и разметку) для форматирования. Вы можете использовать стандартную декомпозицию Unicode, чтобы перейти от математики к буквам (что гораздо более обобщенно).

Giacomo Catenazzi 31.05.2019 10:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
4
167
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

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 31.05.2019 11:37

@daxim хорошо замечен. Чем больше я читаю про юникод, тем больше запутываюсь. Если я вставлю приведенную выше строку с эмодзи в консоль, я увижу \u200D пустое место. Это часть смайлика? Почему у каждого эмодзи по 3 кодовых точки?

adiga 31.05.2019 12:06

@adiga - Это не просто смайлики, все, что связано с метками, имеет ту же проблему. Например, [..."Français"][4] — это c (потому что я написал это с c, за которым следует комбинированный знак для седиля, а не с использованием комбинированного символа ç). Это... не очень весело. :-D normalize может помочь в таких случаях, когда есть эквивалент одного символа, но часто его нет.

T.J. Crowder 03.10.2021 10:55

Символ Юникода выглядит как «\ u00E9», поэтому, если ваша строка длиннее, это нормально. Чтобы иметь реальную длину строки Unicode, вы должны преобразовать ее в массив:

let charArray = [...handwriting]
console.info(charArray.length) //=62

Каждый элемент вашего массива является символом вашей строки. charArray[3] вернет вам символ Юникода, соответствующий «?»

Другие вопросы по теме