Regex: что такое InCombiningDiacriticalMarks? - PullRequest
79 голосов
/ 18 апреля 2011

Следующий код очень хорошо известен для преобразования акцентированных символов в простой текст:

Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

Я заменил свой метод "made made" на этот, но мне нужно понять часть "regex" вthe replaceAll

1) Что такое "InCombiningDiacriticalMarks"?
2) Где находится документация?(и подобные?)

Спасибо.

Ответы [ 2 ]

68 голосов
/ 18 апреля 2011

\p{InCombiningDiacriticalMarks} - это свойство блока Unicode. В JDK7 вы сможете написать его, используя двухсоставную нотацию \p{Block=CombiningDiacriticalMarks}, которая может быть понятнее читателю. Это задокументировано здесь, в UAX # 44: «База данных символов Unicode» .

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

Например, в блоке \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 C ++, как это делает Google, чтобы получить доступ к чему-то вроде \p{BC=NSM}, потому что сейчас только ICU и Perl предоставляют доступ к all 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 много проблем с поддержкой Юникода.

Ой, подожди, я вижу, ты португалец. У вас не должно быть никаких проблем, если вы имеете дело только с португальским текстом.

Тем не менее, вы действительно не хотите удалять акценты, я уверен, что вы хотите быть в состоянии сопоставлять вещи «без учета акцента», верно? Если это так, то вы можете сделать это, используя класс 10 * * ICU4J (ICU для Java) . Если вы сравните в основной силе, знаки акцента не будут учитываться. Я делаю это все время, потому что я часто обрабатываю текст на испанском языке. У меня есть пример того, как это сделать для испанского языка, который сидит где-то здесь, если вам это нужно.

4 голосов
/ 31 марта 2016

Это заняло у меня некоторое время, но я выловил их всех:

Вот регулярное выражение , которое должно включать все символы zalgo, включая те, которые обойдены в «нормальном» диапазоне.

([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F\u0483-\u0486\u05C7\u0610-\u061A\u0656-\u065F\u0670\u06D6-\u06ED\u0711\u0730-\u073F\u0743-\u074A\u0F18-\u0F19\u0F35\u0F37\u0F72-\u0F73\u0F7A-\u0F81\u0F84\u0e00-\u0eff\uFC5E-\uFC62])

Надеюсь, это сэкономит вам время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...