Как имитировать транслитерацию в Java?

В Perl я обычно использую транслитерацию для подсчета количества символов в строке, которые соответствуют набору возможных символов. Вещи как:

$c1=($a =~ y[\x{0410}-\x{042F}\x{0430}-\x{044F}]
            [\x{0410}-\x{042F}\x{0430}-\x{044F}]);

будет считать количество символов кириллицы в $a. Как и в предыдущем примере, у меня есть два класса (или два диапазона, если вы предпочитаете), у меня есть другие с некоторыми другими классами:

$c4=($a =~ y[\x{AC00}-\x{D7AF}\x{1100}-\x{11FF}\x{3130}-\x{318F}\x{A960}-\x{A97F}\x{D7B0}-\x{D7FF}]
            [\x{AC00}-\x{D7AF}\x{1100}-\x{11FF}\x{3130}-\x{318F}\x{A960}-\x{A97F}\x{D7B0}-\x{D7FF}]);

Теперь мне нужно сделать аналогичную вещь в Java. Есть ли подобная конструкция в Java? Или мне нужно перебрать все символы и проверить, находится ли он между пределами каждого класса?

Спасибо

3 ответа

Решение

Не видел ничего подобного tr/// на Яве.

Вы можете использовать что-то вроде этого, чтобы посчитать все совпадения:

Pattern p = Pattern.compile("[\\x{0410}-\\x{042F}\\x{0430}-\\x{044F}]", 
                            Pattern.CANON_EQ);
Matcher m = p.matcher(string);
int count = 0;
while (m.find())
    count++;

Вы можете попробовать поиграть с чем-то вроде этого:

s.replaceAll( "[^\x{0410}-\x{042F}\x{0430}-\x{044F}]*([\x{0410}-\x{042F}\x{0430}-\x{044F}])?", "$1" ).length()

Идея была заимствована отсюда: простой способ подсчета появления символов в строке

Для хорошего порядка: использование поддержки Java Unicode.

int countCyrillic(String s) {
    int n = 0;
    for (int i = 0; i < s.length(); ) {
        int codePoint = s.codePointAt(i);
        i += Character.charCount(codePoint);
        if (UnicodeScript.of(codePoint) == UnicodeScript.CYRILLIC) {
            ++n;
        }
    }
    return n;
}

При этом используется полный Юникод (где два 16-битных символа могут представлять "кодовую точку" Юникода. А в Java класс Character.UnicodeScript уже имеет все, что вам нужно.

Или же:

int n = s.replaceAll("\\P{CYRILLIC}", "").length();

Вот \\P является негативом \\p{CYRILLIC} кириллическая группа.

Другие вопросы по тегам