В Java, как обрабатываются символы Unicode и кодовые точки Java UTF-16? - PullRequest
2 голосов
/ 15 марта 2019

Я борюсь с символами Юникода в Java 10.
Я использую пакет java.text.BreakIterator. Для этого вывод :

myString="a?b"  hex=0061d835dcde0062
myString.length()=4 
myString.codePointCount(0,s.length())=3
BreakIterator output:
    a    hex=0061           
    ?    hex=d835dcde          
    b    hex=0062

Кажется правильным.

Используя тот же код Java, затем с этим выводом :

myString="G̲íl"  hex=0047033200ed006c  
myString.length()=4 
myString.codePointCount(0,s.length())=4
BreakIterator output:   
    G̲    hex=00470332  
    í    hex=00ed  
    l    hex=006c  

Кажется тоже правильным, КРОМЕ для codePointCount = 4.
Почему это не 3, и есть ли способ получить значение 3 без использования BreakIterator?

Моя цель - определить, все ли (выходные) символы строки 16-битные или присутствуют суррогатные или комбинированные символы?

Ответы [ 2 ]

5 голосов
/ 15 марта 2019

"G̲íl" - это четыре кодовые точки: U + 0047, U + 0332, U + 00ED, U + 006C.

U + 0332 является символом объединения, но это - это отдельная кодовая точка.Это не то же самое, что ваш первый пример, который требует использования суррогатной пары (2 единицы кода UTF-16) для представления U + 1D4DE - но последний по-прежнему представляет собой один код point .

BreakIterator находит границы в тексте - здесь объединенные кодовые точки две не имеют границы между ними в этом смысле.Из документации:

Анализ границ символов позволяет пользователям взаимодействовать с символами так, как они ожидают, например, при перемещении курсора по текстовой строке.Анализ границ символов обеспечивает правильную навигацию по строкам символов независимо от того, как хранится символ.

Так что я думаю, что здесь все работает правильно.

1 голос
/ 15 марта 2019

Кодовая точка соответствует одному символу Unicode.

Java представляет Unicode в UTF-16, то есть в 16-битных единицах.Символы со значениями кодовой точки больше, чем U + FFFF, представлены парой «суррогатных символов», как в первом примере.Таким образом, первый результат 3.

Во втором случае у вас есть пример, который не является единственным символом Unicode.Это один символ, буква G, за которым следует другой символ, сочетающий в себе символ LOW LINE.Это две кодовые точки в определении.Таким образом, второй результат 4.

В общем, Unicode имеет таблицы символьных атрибутов (я не уверен, что у меня есть правильное слово здесь), и можно выяснить, что одна из ваших кодовых точек являетсясовмещающий характер.

Посмотрите на класс символов.getType (символ) скажет вам, является ли кодовая точка комбинирующим символом или суррогатом.

...