Обнаружить любой комбинирующий символ в 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 включает в себя диакритические знаки объединения латинского алфавита и т. Д. (Метки, которые в основном идут сверху или снизу и не добавляют ширину к символу).