



Просто проверяю, находится ли буква от A до Z, потому что она не включает буквы с надстрочными знаками или буквы других алфавитов.
Я обнаружил, что вы можете использовать класс регулярных выражений для 'буквы Unicode' или одну из его вариаций с учетом регистра:
string.matches("\p{L}"); // Unicode letter
string.matches("\p{Lu}"); // Unicode upper-case letter
Вы также можете сделать это с помощью класса Характер:
Character.isLetter(character);
но это менее удобно, если вам нужно проверить более одной буквы.
Character.isLetter () намного быстрее, чем string.matches (), потому что string.matches () каждый раз компилирует новый Pattern. Я думаю, что даже кеширование шаблона будет лучше.
Обновлено: Просто наткнулся на это снова и подумал, что попробую найти реальные цифры. Вот моя попытка провести тест, проверяя все три метода (matches() с кэшированием и без кеширования, Pattern и Character.isLetter()). Я также удостоверился, что были проверены как допустимые, так и недопустимые символы, чтобы не искажать вещи.
import java.util.regex.*;
class TestLetter {
private static final Pattern ONE_CHAR_PATTERN = Pattern.compile("\p{L}");
private static final int NUM_TESTS = 10000000;
public static void main(String[] args) {
long start = System.nanoTime();
int counter = 0;
for (int i = 0; i < NUM_TESTS; i++) {
if (testMatches(Character.toString((char) (i % 128))))
counter++;
}
System.out.println(NUM_TESTS + " tests of Pattern.matches() took " +
(System.nanoTime()-start) + " ns.");
System.out.println("There were " + counter + "/" + NUM_TESTS +
" valid characters");
/*********************************/
start = System.nanoTime();
counter = 0;
for (int i = 0; i < NUM_TESTS; i++) {
if (testCharacter(Character.toString((char) (i % 128))))
counter++;
}
System.out.println(NUM_TESTS + " tests of isLetter() took " +
(System.nanoTime()-start) + " ns.");
System.out.println("There were " + counter + "/" + NUM_TESTS +
" valid characters");
/*********************************/
start = System.nanoTime();
counter = 0;
for (int i = 0; i < NUM_TESTS; i++) {
if (testMatchesNoCache(Character.toString((char) (i % 128))))
counter++;
}
System.out.println(NUM_TESTS + " tests of String.matches() took " +
(System.nanoTime()-start) + " ns.");
System.out.println("There were " + counter + "/" + NUM_TESTS +
" valid characters");
}
private static boolean testMatches(final String c) {
return ONE_CHAR_PATTERN.matcher(c).matches();
}
private static boolean testMatchesNoCache(final String c) {
return c.matches("\p{L}");
}
private static boolean testCharacter(final String c) {
return Character.isLetter(c.charAt(0));
}
}
И мой вывод:
10000000 tests of Pattern.matches() took 4325146672 ns. There were 4062500/10000000 valid characters 10000000 tests of isLetter() took 546031201 ns. There were 4062500/10000000 valid characters 10000000 tests of String.matches() took 11900205444 ns. There were 4062500/10000000 valid characters
Так что это почти в 8 раз лучше, даже с кешированным Pattern. (А без кеширования почти в 3 раза хуже, чем кешированный.)
Вы должны использовать
c.codePointAt(0), а неc.charAt(0)вtestCharacter(); в противном случае это не удастся для символов вне BMP.