Ответ 1
\p{InCombiningDiacriticalMarks}
- свойство блока Unicode. В JDK7 вы сможете записать его с использованием двухзначной нотации \p{Block=CombiningDiacriticalMarks}
, которая может быть более понятной для читателя. Документировано здесь, в UAX # 44: "База данных символов Юникода" .
Что это означает, что точка кода попадает в определенный диапазон, блок, который был выделен для использования для вещей под этим именем. Это плохой подход, потому что нет никакой гарантии, что кодовая точка в этом диапазоне является или не является какой-либо конкретной вещью, а не то, что код указывает вне этого блока, не имеет по существу одного и того же символа.
Например, в блоке \p{Latin_1_Supplement}
есть латинские буквы, такие как é, U + 00E9. Однако есть вещи, которые не являются латинскими буквами. И, конечно, есть латинские буквы повсюду.
Блоки почти никогда не нужны.
В этом случае я подозреваю, что вы можете использовать свойство \p{Mn}
, a.k.a. \p{Nonspacing_Mark}
. Все кодовые точки в блоке Combining_Diacriticals относятся к этому типу. Также есть (как Unicode 6.0.0) 1087 Nonspacing_Marks, которые не находятся в этом блоке.
Это почти то же самое, что и проверка \p{Bidi_Class=Nonspacing_Mark}
, но не совсем, потому что в эту группу также входят прилагаемые метки \p{Me}
. Если вы хотите оба, вы можете сказать [\p{Mn}\p{Me}]
, если вы используете механизм регулярных выражений Java по умолчанию, поскольку он дает доступ только к свойству General_Category.
Вам нужно использовать JNI, чтобы получить в библиотеке регулярных выражений ICU С++ способ Google, чтобы получить доступ к чему-то вроде \p{BC=NSM}
, потому что сейчас только ICU и Perl предоставляют доступ ко всем свойствам Unicode. Обычная библиотека Java regex поддерживает только несколько стандартных свойств Unicode. В JDK7, хотя будет поддержка свойства Unicode Script, что почти бесконечно предпочтительнее свойства Block. Таким образом, вы можете в JDK7 написать \p{Script=Latin}
или \p{SC=Latin}
или короткую вырезку \p{Latin}
, чтобы получить любой символ из латинского script. Это приводит к обычному потреблению [\p{Latin}\p{Common}\p{Inherited}]
.
Имейте в виду, что это не удалит то, что вы можете назвать "акцентными" метками от всех персонажей! Их много не будет. Например, вы не можете преобразовать Đ в D или ø в o. Для этого вам нужно уменьшить кодовые точки до тех, которые соответствуют той же самой первичной силе сопоставления в таблице сортировки Unicode.
Другое место, где сбой \p{Mn}
происходит, конечно, заключает в себе отметки типа \p{Me}
, очевидно, но также есть символы \p{Diacritic}
, которые не являются метками. К сожалению, вам нужна полная поддержка собственности для этого, что означает JNI либо для ICU, либо для Perl. Я боюсь, что у Java много проблем с поддержкой Unicode.
Ой, подождите, я вижу, что вы португальцы. У вас не должно быть никаких проблем, если вы имеете дело только с португальским текстом.
Тем не менее, вы действительно не хотите удалять акценты, я готов поспорить, но вы хотите, чтобы быть в состоянии соответствовать вещам "без акцента", верно? Если это так, то вы можете сделать это, используя класс ICU4J (ICU for Java). Если вы сравните с основной силой, знаки акцента не будут считаться. Я делаю это все время, потому что я часто обрабатываю испанский текст. У меня есть пример того, как это сделать для испанца, сидящего где-то здесь, если вам это нужно.