Поиск подстроки – одна из базовых операций при обработке текста в PHP. Несмотря на кажущуюся простоту задачи, выбор подходящей функции зависит от контекста: важна ли чувствительность к регистру, требуется ли позиция первого вхождения или нужно проверить само наличие фрагмента. PHP предоставляет несколько инструментов для этих целей, каждый со своими особенностями.
strpos() – наиболее используемая функция для определения позиции первой подстроки в строке. Она чувствительна к регистру и возвращает позицию первого вхождения или false, если совпадение не найдено. Это позволяет легко реализовать условную логику на основе результата, но требует осторожности: при позиции 0
условие if (strpos(...) != false)
даст ложный результат.
Если требуется игнорировать регистр символов, используется stripos(). Она работает аналогично strpos(), но не различает строчные и прописные буквы. Это важно, например, при разборе пользовательского ввода, где форматирование может отличаться от ожидаемого шаблона.
Для простого определения наличия подстроки часто применяют конструкции на основе !== false. Это гарантирует корректную интерпретацию возвращаемого значения, даже если подстрока находится в начале строки. В случае, когда важна не только позиция, но и количество вхождений, используют substr_count(), возвращающую общее число повторений подстроки в строке.
Понимание различий между этими функциями позволяет избегать логических ошибок и оптимизировать обработку текста в проектах на PHP. Выбор зависит от цели: поиск первого совпадения, игнорирование регистра или подсчёт всех вхождений – для каждой задачи существует свой инструмент.
Как использовать strpos() для поиска первого вхождения подстроки
Функция strpos()
возвращает позицию первого вхождения подстроки в строку, начиная с нуля. Если подстрока не найдена, возвращается false
. Важно учитывать тип возвращаемого значения, так как 0
и false
могут быть ошибочно интерпретированы одинаково.
Пример: strpos("Привет, мир", "мир")
вернёт 8
, поскольку подстрока «мир» начинается с девятого символа (отсчёт с нуля).
Для проверки результата рекомендуется использовать оператор идентичности: if (strpos($text, $substr) !== false)
. Это исключает ложные срабатывания при позиции 0.
Функция чувствительна к регистру. Вызов strpos("Пример", "п")
вернёт false
, так как «П» и «п» – разные символы.
Третий аргумент позволяет задать смещение поиска. strpos("тест тест", "т", 5)
вернёт 5
, начиная поиск с шестого символа.
Не используйте strpos()
для проверки наличия подстроки в логическом контексте без строгого сравнения с false
– это распространённая причина скрытых ошибок.
Чем отличается stripos() и когда использовать нечувствительный поиск
stripos() – функция PHP, возвращающая позицию первого вхождения подстроки в строке без учёта регистра символов. В отличие от strpos(), она воспринимает ‘A’ и ‘a’ как равные, что критично при обработке пользовательского ввода, поиске по текстам и анализе данных с переменным регистром.
Для получения всех позиций вхождений подстроки в строку используется функция strpos()
внутри цикла while
. Необходимо отслеживать позицию последнего найденного вхождения и передавать её в качестве второго аргумента – смещения поиска.
Пример:
$string = "abc abc abc";
$substring = "abc";
$positions = [];
$offset = 0;
while (($pos = strpos($string, $substring, $offset)) !== false) {
$positions[] = $pos;
$offset = $pos + 1;
}
print_r($positions);
Результат выполнения: [0, 4, 8]
. Это индексы всех вхождений подстроки "abc"
в строке. Смещение $offset = $pos + 1
гарантирует, что поиск продолжается после предыдущего найденного вхождения, предотвращая зацикливание при повторяющихся фрагментах.
Не используйте substr()
для обхода строки – это замедляет выполнение и расходует память. strpos()
с явным указанием смещения работает быстрее и точнее.
Для поиска с учётом регистра используйте strpos()
, а для без учёта регистра – stripos()
. Алгоритм остаётся идентичным.
Как проверить, начинается ли строка с подстроки
Для проверки начала строки на соответствие подстроке в PHP используют функцию str_starts_with(), доступную с версии 8.0. Она возвращает true, если строка начинается с указанной подстроки:
Пример:
$str = "example.com";
$result = str_starts_with($str, "exam"); // true
Если используется версия PHP ниже 8.0, можно применить substr() в сочетании с strlen():
$str = "example.com";
$prefix = "exam";
$result = substr($str, 0, strlen($prefix)) === $prefix; // true
Функция strncmp() также подходит для этой задачи, особенно при работе с ограничением по символам:
$result = strncmp($str, $prefix, strlen($prefix)) === 0; // true
Избегайте strpos() для этой цели: оно не учитывает позицию начала строки и может вернуть ложноположительный результат, если подстрока находится внутри строки.
Как определить, содержится ли подстрока в строке с помощью str_contains()
Функция str_contains()
появилась в PHP 8. Она возвращает true
, если указанная подстрока найдена в строке, и false
– в противном случае. Возвращаемое значение имеет тип bool
.
Сигнатура функции: str_contains(string $haystack, string $needle): bool
. Первый аргумент – строка, в которой выполняется поиск. Второй – подстрока, которую необходимо найти.
Пример: str_contains("openai.com", "ai")
вернёт true
, так как подстрока «ai» содержится в строке «openai.com».
Функция чувствительна к регистру. str_contains("Test", "t")
вернёт true
, а str_contains("Test", "T")
также вернёт true
, но str_contains("Test", "x")
даст false
.
Перед использованием str_contains()
следует убедиться, что версия PHP не ниже 8.0. Для обратной совместимости можно использовать конструкцию strpos() !== false
, но str_contains()
делает код чище и безопаснее.
Пустая подстрока всегда считается найденной: str_contains("abc", "")
вернёт true
. Это поведение важно учитывать при валидации входных данных.
Обработка ошибок при поиске подстроки: типичные ошибки и их решение
При использовании функций strpos()
, strrpos()
и аналогичных важно учитывать тонкости их поведения, чтобы избежать логических ошибок и неожиданных результатов.
- Ошибка: игнорирование возвращаемого значения
0
Функция
strpos()
возвращает0
, если подстрока найдена в начале строки. Многие проверяют результат с помощью конструкцииif (strpos(...))
, что приводит к ложному отрицанию.Решение: используйте строгое сравнение
!== false
, чтобы отличать0
отfalse
:if (strpos($text, $needle) !== false) { ... }
- Ошибка: использование
strpos()
без проверки типаЕсли передать нестроковые аргументы, PHP попытается преобразовать их в строки, что может привести к неожиданному поведению или предупреждениям.
Решение: проверяйте типы аргументов с помощью
is_string()
до вызова:if (is_string($haystack) && is_string($needle)) { strpos($haystack, $needle); }
- Ошибка: поиск пустой подстроки
Поиск пустой строки (
strpos($text, "")
) всегда возвращает0
, что может быть неочевидным источником ошибок.Решение: добавляйте явную проверку на пустоту подстроки перед вызовом функции:
if ($needle !== "") { strpos($text, $needle); }
- Ошибка: использование
strpos()
в контексте, где требуется точное совпадениеstrpos()
ищет вхождение, но не проверяет, равны ли строки. Это может привести к ложным совпадениям.Решение: используйте
===
для сравнения строк, если нужно полное совпадение:if ($text === $needle) { ... }
- Ошибка: неучтённая кодировка при работе с многобайтовыми строками
strpos()
работает побайтно. Для UTF-8 строк возможен некорректный результат при наличии многобайтовых символов.Решение: используйте
mb_strpos()
с указанием кодировки:mb_strpos($text, $needle, 0, 'UTF-8');