Как имитировать транслитерацию в 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}
кириллическая группа.