1. Обзор
Существует множество способов проверить, содержит ли строка подстроку . В этой статье мы будем искать подстроки внутри String , сосредоточившись на обходных путях без учета регистра для String.contains() в Java. Самое главное, мы приведем примеры того, как решить эту проблему.
2. Самое Простое Решение: Строка.toLowerCase
Самое простое решение-использовать String.toLowerCase() . В этом случае мы преобразуем обе строки в нижний регистр, а затем используем метод contains() :
assertTrue(src.toLowerCase().contains(dest.toLowerCase()));
Мы также можем использовать String.toUpperCase (), и это даст тот же результат.
3. Строка.спички С Регулярными Выражениями
Другой вариант-использовать String.matches() с регулярными выражениями:
assertTrue(src.matches("(?i).*" + dest + ".*"));
Метод matches() принимает как попытку представить регулярное выражение. (?i) включает нечувствительность к регистру и .* использует все символы, кроме разрывов строк.
4. String.regionMatches
Мы также можем использовать String.regionMatches() . Он проверяет, совпадают ли две области String , используя true для параметра IgnoreCase :
public static boolean processRegionMatches(String src, String dest) { for (int i = src.length() - dest.length(); i >= 0; i--) if (src.regionMatches(true, i, dest, 0, dest.length())) return true; return false; }
assertTrue(processRegionMatches(src, dest));
Чтобы повысить производительность, он начинает сопоставлять регион с учетом длины целевой строки . Затем он уменьшает итератор.
5. Шаблон С параметром CASE_INSENSITIVE
Класс java.util.regex.Pattern предоставляет нам способ сопоставления строк с помощью метода matcher () . В этом случае мы можем использовать метод quote() для экранирования любых специальных символов и флаг CASE_INSENSITIVE . Давайте посмотрим:
assertTrue(Pattern.compile(Pattern.quote(dest), Pattern.CASE_INSENSITIVE) .matcher(src) .find());
6. Apache Commons StringUtils.containsIgnoreCase
Наконец, мы воспользуемся классом Apache Commons StringUtils:
assertTrue(StringUtils.containsIgnoreCase(src, dest));
7. Сравнение Производительности
Как и в этой общей статье о проверке подстрок с помощью метода contains , мы использовали фреймворк с открытым исходным кодом Java Microbenchmark Harness (JMH) для сравнения производительности методов в наносекундах :
- Регулярное выражение Pattern CASE_INSENSITIVE : 399.387 нс
- Строка toLowerCase : 434.064 ns
- Apache Commons StringUtils : 496.313 ns
- Совпадения области строки : 718.842 нс
- Строка совпадает с регулярным выражением : 3964.346 ns
Как мы видим, победителем является Pattern с включенным флагом CASE_INSENSITIVE , за которым следует toLowerCase() . Мы также заметили явное улучшение производительности между Java 8 и Java 11.
8. Заключение
В этом уроке мы рассмотрели несколько различных способов проверки String на наличие подстроки, игнорируя при этом случай в Java.
Мы рассмотрели использование String.toLowerCase() и toUpperCase() , String.matches() , String.regionMatches() , Apache Commons StringUtils.containsIgnoreCase() , и Pattern.matcher().find() .
Кроме того, мы оценили производительность каждого решения и обнаружили, что использование метода compile() из java.util.regex.Pattern с флагом CASE_INSENSITIVE работает лучше всего .
Как всегда, код доступен на GitHub .