W3docs

Как проверить, содержит ли строка подстроку в Java

Проверка подстроки в Java: contains, indexOf, startsWith, endsWith и регулярные выражения.

Проверка того, входит ли одна String в другую, — одна из самых распространённых текстовых задач в Java. Выбор инструмента зависит от того, что именно нужно: простой ответ да/нет, позиция совпадения, проверка с привязкой к началу или концу строки или гибкий шаблон. В этой главе рассматривается каждый идиоматический подход и когда к нему обращаться.

Основной способ: String.contains

Когда нужен лишь boolean — «есть ли этот фрагмент в строке?» — contains является наиболее понятным выбором:

String text = "The quick brown fox";
boolean hasFox = text.contains("fox");   // true
boolean hasCat = text.contains("cat");   // false

contains принимает любой CharSequence (то есть String, StringBuilder и т. д.) и возвращает true, если аргумент встречается в строке хотя бы один раз. Метод чувствителен к регистру: text.contains("FOX") вернёт false. Один граничный случай, который стоит помнить, — пустая строка содержится в каждой строке, поэтому text.contains("") всегда возвращает true.

Когда нужна позиция: indexOf

contains фактически реализован поверх indexOf. Если нужно знать, где начинается совпадение (или нужно найти все вхождения), вызовите indexOf напрямую:

String text = "The quick brown fox";
int at = text.indexOf("brown");   // 10
int no = text.indexOf("bird");    // -1

indexOf возвращает индекс первого совпадения (с нуля) или -1, если подстрока отсутствует. Классическая проверка принадлежности выглядит как text.indexOf("brown") >= 0 — это эквивалент contains, но заодно даёт позицию совпадения. Существует также lastIndexOf для поиска с конца строки и перегрузка с начальным смещением для поиска последующих вхождений в цикле.

Проверки с привязкой: startsWith и endsWith

Если важно именно начало или конец строки — расширения файлов, префиксы URL, схемы протоколов — startsWith и endsWith выражают намерение напрямую и читаются лучше, чем срезы:

String file = "report.pdf";
boolean isPdf  = file.endsWith(".pdf");      // true
boolean isHttp = "https://w3docs.com".startsWith("https://"); // true

Эти методы быстрее и понятнее, чем indexOf(prefix) == 0, поскольку прекращают сравнение при первом несовпадении символов и не сканируют всю строку.

Проверка без учёта регистра и сопоставление с шаблоном

У contains нет перегрузки без учёта регистра. Простейшее решение — привести обе стороны к одному регистру:

boolean ci = text.toLowerCase().contains("FOX".toLowerCase()); // true

Для чего-то более сложного, чем буквальный фрагмент — альтернативы, подстановочные символы, границы слов — используйте регулярные выражения. Pattern.compile(...).matcher(text).find() возвращает true, если шаблон совпадает в любом месте строки, а CASE_INSENSITIVE обрабатывает регистр без создания копий в нижнем регистре:

import java.util.regex.Pattern;
boolean found = Pattern.compile("fox", Pattern.CASE_INSENSITIVE)
                       .matcher(text).find();
ПодходВозвращаетПрименять когда
containsbooleanПростая проверка принадлежности, буквальный текст
indexOfint (позиция или -1)Нужно знать где находится совпадение
startsWith / endsWithbooleanПривязка к началу или концу строки
Pattern.findbooleanШаблоны, альтернативы, без учёта регистра

Разобранный пример

Эта программа выполняет четыре подхода параллельно на одном предложении, включая особенность чувствительности к регистру и граничный случай с пустой строкой.

java— editable, runs on the server

Что можно вынести из выполнения программы:

  • contains "brown" выводит true, а contains "cat" выводит falsecontains является прямым boolean-тестом принадлежности для буквального текста.
  • contains "FOX" выводит false, хотя слово "fox" присутствует в строке — это подтверждает, что contains чувствителен к регистру; нормализованная строка contains "FOX" (ci) выводит true.
  • indexOf "fox" выводит 16 — позицию начала совпадения с нуля, а indexOf "bird" выводит -1, сигнализируя «не найдено» — именно это значение -1 используется как контрольное в проверке.
  • startsWith "The" и endsWith "dog" оба выводят true, демонстрируя привязанные проверки самого начала и самого конца предложения.
  • contains "" выводит true — напоминание о том, что каждая строка содержит пустую строку; следует защититься от пустых входных данных, если это может быть ошибкой.

Связанные темы

  • Java Strings — основа для каждого метода на этой странице.
  • Java String Methods — полный справочник по contains, indexOf, startsWith и другим методам.
  • How to Compare Strings in Java — равенство и порядок — логическое продолжение после проверки принадлежности.
  • Java Regex: Pattern and Matcher — более глубокое изучение подхода на основе шаблонов, рассмотренного выше.

Практика

Практика
Что вернёт text.indexOf('bird'), если 'bird' отсутствует в строке text?
Что вернёт text.indexOf('bird'), если 'bird' отсутствует в строке text?
Was this page helpful?