Как проверить, содержит ли строка подстроку в 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"); // falsecontains принимает любой 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"); // -1indexOf возвращает индекс первого совпадения (с нуля) или -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();| Подход | Возвращает | Применять когда |
|---|---|---|
contains | boolean | Простая проверка принадлежности, буквальный текст |
indexOf | int (позиция или -1) | Нужно знать где находится совпадение |
startsWith / endsWith | boolean | Привязка к началу или концу строки |
Pattern.find | boolean | Шаблоны, альтернативы, без учёта регистра |
Разобранный пример
Эта программа выполняет четыре подхода параллельно на одном предложении, включая особенность чувствительности к регистру и граничный случай с пустой строкой.
Что можно вынести из выполнения программы:
contains "brown"выводитtrue, аcontains "cat"выводитfalse—containsявляется прямым 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 — более глубокое изучение подхода на основе шаблонов, рассмотренного выше.