Обнаружить любой комбинирующий символ в Java

Я ищу способ определить, является ли символ в строке Java "комбинирующим символом" или нет. Например,

String khmerCombiningVowel = 
 new String(new byte[]{(byte) 0xe1,(byte) 0x9f,(byte) 0x80}, "UTF-8"); // unicode 17c0

представляет собой объединяющий кхмерский гласный знак. я пытался "\\p{InCombiningDiacriticalMarks}" регулярное выражение, но, кажется, это не относится к этим конкретным объединяющим персонажам. Или даже если есть какой-то исчерпывающий список всех блоков символов, объединяющих юникод, я мог бы сделать для них регулярное выражение?

1 ответ

Решение

Согласно Алгоритму проверки на объединение символов в Юникоде существует несколько блоков для объединения символов.

Java имеет ряд полезных функций, попробуйте:

String codePointStr = new String(new byte[]{(byte) 0xe1, (byte) 0x9f, (byte) 0x80}, "UTF-8"); // unicode 17c0
System.out.println(codePointStr.matches("\\p{Mc}"));
System.out.println(
    Character.COMBINING_SPACING_MARK == Character.getType(codePointStr.codePointAt(0)));

(печатает true в обоих случаях)

В этом случае COMBINING_SPACING_MARK (и соответствующее регулярное выражение \p{gc=Mc}) оба относятся к категории Unicode "Mark, Spacing Combining", которая в основном представляет собой любой символ, который комбинируется с предыдущим символом при добавлении ширины.

Другие регулярные выражения, которые могут быть полезны: \p{M} для любой марки. Если вы хотите использовать персонажа getType() константы, вы можете получить то же поведение, проверив, если его тип COMBINING_SPACING_MARK или же ENCLOSING_MARK, или же NON_SPACING_MARK,

ENCLOSING_MARK - это окружающий символ, например, круг - также добавляет ширину символу, с которым он сочетается.

NON_SPACING_MARK включает в себя диакритические знаки объединения латинского алфавита и т. Д. (Метки, которые в основном идут сверху или снизу и не добавляют ширину к символу).

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