Я читал документацию для StringBuffer
, в частности, метода reverse () . Эта документация упоминает что-то о суррогатных парах . Что такое суррогатная пара в этом контексте? А что такое низкие и высокие суррогаты?
java
unicode
utf-16
surrogate-pairs
Раймонд
источник
источник
String
сделать, а не только символьные. Жаль, что Java не позволяет вам использовать OO, чтобы исправить это, но иString
класс, иStringBuffer
классы былиfinal
изменены. Скажите, разве это не эвфемизм для убитых? :)Ответы:
Термин «суррогатная пара» относится к средству кодирования символов Unicode с высокими кодовыми точками в схеме кодирования UTF-16.
В кодировке Unicode символы отображаются в значения между 0x0 и 0x10FFFF.
Внутренне Java использует схему кодирования UTF-16 для хранения строк текста Unicode. В UTF-16 используются 16-битные (двухбайтовые) кодовые единицы. Поскольку 16 бит могут содержать только диапазон символов от 0x0 до 0xFFFF, некоторая дополнительная сложность используется для хранения значений выше этого диапазона (от 0x10000 до 0x10FFFF). Это делается с помощью пар кодовых единиц, известных как суррогаты.
Единицы суррогатного кода находятся в двух диапазонах, известных как «высокие суррогаты» и «низкие суррогаты», в зависимости от того, разрешены ли они в начале или в конце последовательности из двух единиц кода.
источник
Ранние версии Java представляли символы Unicode, используя 16-битный тип данных char. В то время этот дизайн имел смысл, потому что все символы Юникода имели значения меньше 65 535 (0xFFFF) и могли быть представлены в 16 битах. Позже, однако, Unicode увеличил максимальное значение до 1,114,111 (0x10FFFF). Поскольку 16-разрядные значения были слишком малы для представления всех символов Unicode в версии 3.1 Unicode, 32-разрядные значения, называемые кодовыми точками, были приняты для схемы кодирования UTF-32. Но 16-битные значения предпочтительнее 32-битных для эффективного использования памяти, поэтому Unicode представил новый дизайн, позволяющий продолжать использовать 16-битные значения. Эта конструкция, принятая в схеме кодирования UTF-16, присваивает 1024 значения 16-разрядным старшим суррогатам (в диапазоне U + D800 - U + DBFF) и еще 1024 значения 16-разрядным старшим суррогатам (в диапазоне U + DC00) до U + DFFF).
источник
Эта документация говорит о том, что недопустимые строки UTF-16 могут стать действительными после вызова
reverse
метода, поскольку они могут быть обращены к действительным строкам. Суррогатная пара (обсуждаемая здесь ) - это пара 16-битных значений в UTF-16, которые кодируют одну кодовую точку Unicode; низкие и высокие суррогаты - это две половины этого кодирования.источник
Добавление дополнительной информации к ответам выше из этого поста.
Протестировано в Java-12, должно работать во всех версиях Java выше 5.
Как упомянуто здесь: https://stackoverflow.com/a/47505451/2987755 ,
какой символ (чей Unicode выше U + FFFF) представлен как суррогатная пара, которую Java хранит в виде пары значений char, то есть одного Unicode символ представлен в виде двух смежных символов Java.
Как мы можем видеть в следующем примере.
1. Длина:
2. Равенство.
Представьте «🌉» в строке, используя Unicode,
\ud83c\udf09
как показано ниже, и проверьте равенство.Java не поддерживает UTF-32
3. Вы можете преобразовать символ Unicode в строку Java
4. String.substring () не учитывает дополнительные символы
Чтобы решить это, мы можем использовать
String.offsetByCodePoints(int index, int codePointOffset)
5. Строка Итерация Unicode с BreakIterator
6. Сортировка строк с Unicode java.text.Collator
7. персонажа
toUpperCase()
,toLowerCase()
методы не должны использоваться, вместо этого, используйте строку в верхний регистр и нижний регистр в конкретной местности.8.
Character.isLetter(char ch)
не поддерживает, лучше используетCharacter.isLetter(int codePoint)
, для каждогоmethodName(char ch)
метода в классе Character будет тип,methodName(int codePoint)
который может обрабатывать дополнительные символы.9. Укажите кодировку
String.getBytes()
, преобразуя из байтов в строкуInputStreamReader
,OutputStreamWriter
Ссылка:
https://coolsymbol.com/emojis/emoji-for-copy-and-paste.html#objects
https://www.online-toolz.com/tools/text-unicode-entities-convertor.php
https: //www.ibm.com/developerworks/library/j-unicode/index.html
https://www.oracle.com/technetwork/articles/javaee/supplementary-142654.html
Больше информации на примере image1 image2
Другие термины, которые стоит изучить: нормализация , BiDi
источник
Суррогатные пары относятся к способу кодирования определенных символов в UTF-16, см. Http://en.wikipedia.org/wiki/UTF-16/UCS-2#Code_points_U.2B10000..U.2B10FFFF.
источник
Небольшое предисловие
До версии 3.1 в основном использовались 8-битное кодирование, известное как UTF-8, и 16-битное кодирование, известное как UCS-2 или «Универсальный набор символов, закодированный в 2 октета». UTF-8 кодирует точки Unicode как последовательность 1-байтовых блоков, в то время как UCS-2 всегда занимает 2 байта:
A = 41 - один блок из 8 битов с UTF-8
A = 0041 - один блок из 16 битов с UCS-2
Ω = CE A9 - два блока из 8 битов с UTF-8
Ω = 03A9 - один блок из 16 бит с UCS-2
проблема
Консорциум полагал, что 16 бит будет достаточно для охвата любого понятного человеку языка, что дает 2 ^ 16 = 65536 возможных значений кода. Это было верно для плоскости 0, также известной как BPM или базовая многоязычная плоскость, которая включает 55,445 из 65536 кодовых точек сегодня. BPM охватывает практически все человеческие языки в мире, включая китайско-японско-корейские символы (CJK).
Прошло время, и были добавлены новые азиатские наборы символов, китайские символы набрали более 70000 баллов. Теперь есть даже очки Emoji как часть стандартного 😺. Новые 16 "дополнительных" самолетов были добавлены. Помещения UCS-2 было недостаточно, чтобы покрыть что-то большее, чем Plane-0.
Решение Unicode
Создайте UTF-16 на основе UCS-2. Сделайте UTF-16 динамическим, чтобы он занимал 2 байта или 4 байта на точку. Присвойте 1024 балла U + D800 – U + DBFF, называемых High Surrogates, UTF-16; назначить 1024 символа U + DC00-U + DFFF, называемых Low Surrogates, UTF-16.
С этими изменениями BPM покрывается 1 блоком из 16 битов в UTF-16, тогда как все «дополнительные символы» покрываются суррогатными парами, представляющими 2 блока по 16 битов каждый, всего 1024x1024 = 1 048 576 точек.
Высокий суррогат предшествует низкому суррогату . Любое отклонение от этого правила считается плохой кодировкой. Например, суррогат без пары неверен, низкий суррогат стоит перед старшим суррогатом неверен.
𝄞, «MUSICAL SYMBOL G CLEF», кодируется в UTF-16 как пара суррогатов 0xD834 0xDD1E (2 на 2 байта),
в UTF-8 как 0xF0 0x9D 0x84 0x9E (4 на 1 байт),
в UTF-32 как 0x0001D11E (1 на 4 байта).
Текущая ситуация
Для поддержки устаревших приложений с некорректными кодировками UTF-8 / UTF-16 был создан новый стандарт WTF-8 , Wobbly Transformation Format. Он поддерживает произвольные суррогатные точки, такие как непарный суррогат или неправильная последовательность. Сегодня некоторые продукты не соответствуют стандарту и рассматривают UTF-8 как WTF-8.
Многие исторические детали были скрыты, чтобы следовать теме ⚖.
Последний стандарт Unicode можно найти по адресу http://www.unicode.org/versions/latest.
источник
Суррогатная пара - это две «кодовые единицы» в UTF-16, которые составляют одну «кодовую точку». В документации Java говорится, что эти «кодовые точки» все еще будут действительны, а их «кодовые единицы» будут упорядочены правильно после обратного. Далее говорится, что две непарные единицы суррогатного кода могут быть обращены и образовать действительную суррогатную пару. Это означает, что если есть непарные кодовые блоки, то есть вероятность того, что обратная сторона реверса может не совпадать!
Однако обратите внимание, что в документации ничего не говорится о графемах - которые объединяют несколько кодовых точек. Это означает, что e и акцент, который идет вместе с ним, могут все еще быть переключены, таким образом, помещая акцент перед e. Это означает, что если перед е есть еще один гласный, он может получить ударение, которое было на е.
Хлоп!
источник