Очень хорошо известен следующий код для преобразования символов с диакритическими знаками в обычный текст:
Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
Я заменил свой метод "ручной работы" на этот, но мне нужно понимать "регулярное выражение" в replaceAll
1) Что такое «InCombiningDiacriticalMarks»?
2) Где это документация? (и подобные?)
Спасибо.
Ответы:
\p{InCombiningDiacriticalMarks}
является свойством блока Unicode. В JDK7 вы сможете написать его, используя двухчастную нотацию\p{Block=CombiningDiacriticalMarks}
, которая может быть более понятной для читателя. Это задокументировано здесь, в UAX № 44: «База данных символов Unicode» .Это означает, что кодовая точка попадает в конкретный диапазон, блок, который был выделен для использования для вещей под этим именем. Это плохой подход, потому что нет гарантии, что кодовая точка в этом диапазоне является или не является какой-либо конкретной вещью, или что кодовые точки за пределами этого блока не имеют по существу одного и того же символа.
Например, в
\p{Latin_1_Supplement}
блоке есть латинские буквы , такие как é, U + 00E9. Однако там есть вещи, которые не являются латинскими буквами. И, конечно же, повсюду встречаются латинские буквы.Блоки - это почти никогда не то, что вам нужно.
В этом случае я подозреваю, что вы можете захотеть использовать свойство
\p{Mn}
, также известное как\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 C ++, как это делает Google, чтобы получить доступ к чему-то вроде
\p{BC=NSM}
, потому что сейчас только ICU и Perl предоставляют доступ ко всем свойствам Unicode. Обычная библиотека регулярных выражений Java поддерживает только несколько стандартных свойств Unicode. Однако в JDK7 будет поддержка свойства Unicode Script, которое почти бесконечно предпочтительнее свойства Block. Таким образом, в JDK7 вы можете написать\p{Script=Latin}
или\p{SC=Latin}
, или сокращенно\p{Latin}
, получить любой символ из латинского алфавита. Это приводит к очень часто необходимым[\p{Latin}\p{Common}\p{Inherited}]
.Имейте в виду, что это не приведет к удалению того, что вы могли бы подумать как «акцентные» знаки со всех символов! Для многих это не годится. Например, вы не можете преобразовать Đ в D или ø в o таким образом. Для этого вам нужно уменьшить количество кодовых точек до тех, которые соответствуют той же основной силе сопоставления в таблице сопоставления Unicode.
Другое место, где что-
\p{Mn}
то не работает, - это, конечно, пометки вроде\p{Me}
, очевидно, но также есть\p{Diacritic}
символы, которые не являются знаками. К сожалению, для этого вам нужна полная поддержка свойств, что означает JNI для ICU или Perl. Боюсь, у Java много проблем с поддержкой Unicode.Ой, подождите, я вижу, вы португальцы. У вас не должно возникнуть никаких проблем, если вы имеете дело только с португальским текстом.
Однако я уверен, что вы действительно не хотите убирать акценты, а скорее хотите иметь возможность сочетать вещи «без учета акцента», верно? Если да, то вы можете сделать это с помощью класса сопоставителя ICU4J (ICU для Java) . Если вы сравните по основной силе, акцентные знаки не будут учитываться. Я делаю это все время, потому что часто обрабатываю испанский текст. У меня есть пример того, как это сделать для испанцев, сидящих где-нибудь здесь, если вам это нужно.
источник
Мне потребовалось время, но я выловил их всех:
Вот регулярное выражение, которое должно включать все символы zalgo, включая те, которые были обойдены в «нормальном» диапазоне.
Надеюсь, это сэкономит вам время.
источник