Перейти к основному содержимому

Сопоставление строк без учета регистра в Java

· 3 мин. чтения

1. Обзор

Есть много способов проверить, содержит ли строка подстроку . В этой статье мы будем искать подстроки в String , сосредоточив внимание на нечувствительных к регистру обходных решениях для String.contains() в Java. Самое главное, мы предоставим примеры того, как решить эту проблему.

2. Самое простое решение: String.toLowerCase

Самое простое решение — использовать String.toLowerCase() . В этом случае мы преобразуем обе строки в нижний регистр, а затем используем метод contains() :

assertTrue(src.toLowerCase().contains(dest.toLowerCase()));

Мы также можем использовать String.toUpperCase() , и это даст тот же результат.

3. String.matches с регулярными выражениями

Другой вариант — использовать String.matches() с регулярными выражениями:

assertTrue(src.matches("(?i).*" + dest + ".*"));

Метод match() принимает строку S для представления регулярного выражения. (?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));

Для повышения производительности он начинает сопоставлять регион с учетом длины целевой строки String . Затем он уменьшает итератор.

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) для сравнения производительности методов в наносекундах :

  1. Шаблон CASE_INSENSITIVE Регулярное выражение : 399,387 нс
  2. Строка toLowerCase : 434,064 нс
  3. Apache Commons StringUtils : 496,313 нс
  4. Совпадения строковых областей : 718,842 нс
  5. Строка соответствует регулярному выражению : 3964,346 нс

Как мы видим, победителем является Pattern с включенным флагом CASE_INSENSITIVE , за которым следует toLowerCase() . Мы также заметили явное улучшение производительности между Java 8 и Java 11.

8. Заключение

В этом руководстве мы рассмотрели несколько различных способов проверки строки на наличие подстроки, игнорируя регистр в Java.

Мы рассмотрели использование String.toLowerCase() и toUpperCase() , String.matches() , String.regionMatches() , Apache Commons StringUtils.containsIgnoreCase() и Pattern.matcher().find() .

Кроме того, мы оценили производительность каждого решения и обнаружили, что использование метода compile() из java.util.regex.Pattern с флагом CASE_INSENSITIVE показало лучшие результаты .

Как всегда, код доступен на GitHub .