#регулярные_выражения #unicode
Можно ли полагаться на то, что JVM «умным образом» разрешает диапазон "а-я" или "a-z" в регулярном выражении и добавляет в него все символы некоторого алфавита, который начинается на «а» и заканчивается на «я»? Ответ: нет, диапазон читается буквально, и это можно подтвердить экспериментом. Символы Ё и ё не попадают в диапазон юникода, в котором лежат все кириллические символы русского языка. То же самое верно для существенной части других алфавитов: буквы в Unicode идут не подряд. Предлагаю отвлечься от особенностей кириллицы и подумать об абстрактном "a-z", где "a" и "z" — первая и последняя буква какого-то алфавита. Есть ли в Java готовое решение для того, чтобы описать все "родные" буквы в заданной локали? Ответ: в Java нет, но есть в ответе к этому вопросу Нашел про поддержку локалей, но не вполне представляю, как это можно применить в регулярном выражении. Логично бы ожидать character class, какой-нибудь \p{locale_Ru_Ru}, но не нахожу. Навеяно этим ответом к вопросу «Как определить не русский текст?»
Ответы
Ответ 1
Регулярки просто включают диапазон между порядковыми значениями символов. Полный кириллический диапазон безусловно включает Ёё и многое другое. Так что, чтобы собрать базовую кириллицу, достаточно задать диапазон вида [\x400-\x4ff] (не уверен что точный синтаксис для этого формата в Java).Ответ 2
Готовые выражения для всех символов в заданной локали Все ответы, где отдельно не указан источник, основаны на Useful ASCII Ranges. Этот ответ основан на ответе stribizhev на EN.SO. Кроме первых двух, отсортировано по алфавиту. Русский алфавит (wikipedia) [а-яА-ЯёЁ] Вся латиница плюс акцентированные символы (?![×÷])[A-Za-zÀ-ÿ] Белорусский алфавит (wikipedia) [ёа-зй-шы-яЁА-ЗЙ-ШЫІіЎў] Болгарский алфавит (является подмножеством русского) (wikipedia) [а-ъьюяА-ЪЬЮЯ] Греческий и коптский алфавиты вместе: (wikipedia) [\u0370-\u03FF\u1F00-\u1FFF] Испанский алфавит [a-zA-ZáéíñóúüÁÉÍÑÓÚÜ] Итальянский алфавит [a-zA-ZàèéìíîòóùúÀÈÉÌÍÎÒÓÙÚ] Немецкий алфавит [a-zA-ZäöüßÄÖÜẞ] Норвежский алфавит (wikipedia) [a-zA-ZæøåÆØÅ] Польский алфавит [a-pr-uwy-zA-PR-UWY-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ] В польском языке нет заглавных букв Q, V and X. Если нужен польский + латиница: [a-zA-ZąćęłńóśźżĄĆĘŁŃÓŚŹŻ] Румынский алфавит (wikipedia) [a-zA-ZĂÂÎȘȚăâîșț] Сербский алфавит (кириллица) (wikipedia) [А-ИК-ШЂЈ-ЋЏа-ик-шђј-ћџ] Украинский (wikipedia) Апостроф — тоже буква. [а-щА-ЩЬьЮюЯяЇїІіЄєҐґ'] Французский алфавит [a-zA-ZàâäôéèëêïîçùûüÿæœÀÂÄÔÉÈËÊÏΟÇÙÛÜÆŒ] Шведский алфавит (wikipedia) [a-zA-ZäöåÄÖÅ]Ответ 3
Самому стало интересно как все это будет выглядеть в диапазонах символов: int c = Character.MIN_VALUE; int low = -1; Pattern pat = Pattern.compile( "^[а-яА-Я]$" ); while ( c <= (int) Character.MAX_VALUE ) { if ( pat.matcher( String.valueOf( (char) c ) ).matches() ) { if ( low == -1 ) low = c; } else { if ( low > -1 ) { System.out.println( Integer.toHexString( low ) + " - " + Integer.toHexString(c-1) ); low = -1; } } c++; } Для данной регулярки это 410 - 44f Так что решается все очень просто: как и написал @Petr Abdulin
Комментариев нет:
Отправить комментарий