Menu

PHP strpos(): найти позицию подстроки

strpos($haystack, $needle) возвращает позицию первого вхождения $needle или false, если оно не найдено. Проверка !== false, stripos без учёта регистра, последнее совпадение через strrpos и поиск всех вхождений.

На этой странице есть исполняемые редакторы: меняйте, запускайте и сразу видите результат.

strpos($haystack, $needle) возвращает позицию первого $needle внутри $haystack, считая с 0, или false, если его там нет. Всегда проверяйте результат через !== false, потому что совпадение в начале возвращает 0.

Если в PHP 8 нужен только ответ "да" или "нет", str_contains() понятнее. Используйте strpos(), когда важна позиция.

Синтаксис

strpos(string $haystack, string $needle, int $offset = 0): int|false

Поиск учитывает регистр. $offset задаёт, откуда начинать поиск; отрицательное смещение отсчитывается с конца строки.

Ловушка !== false

0 и false равны при нестрогом сравнении (==). Поэтому любая нестрогая проверка считает совпадение на позиции 0 "не найденным".

То же правило касается stripos(), strrpos() и array_search(): все они могут вернуть 0 для настоящего совпадения.

Поиск без учёта регистра через stripos

stripos() принимает те же аргументы и не учитывает регистр ASCII-букв.

Последнее вхождение через strrpos

strrpos() возвращает позицию последнего совпадения. Это стандартный способ получить расширение файла или последний сегмент пути.

Для имён файлов это за вас делает pathinfo($file, PATHINFO_EXTENSION). Как вырезать часть строки по позиции, рассказано на странице substr().

Поиск со смещением

Третий аргумент пропускает начало строки. Отрицательное смещение начинает за столько символов до конца.

Поиск всех вхождений

strpos() находит одно совпадение. Чтобы найти все, используйте цикл и сдвигайте смещение за каждое совпадение:

Нужно только количество? Короче substr_count($text, 'the'). Для шаблонов preg_match_all() с PREG_OFFSET_CAPTURE возвращает каждое совпадение с его позицией.

Японский текст: позиция в байтах и позиция в символах

strpos() правильно находит многобайтовый текст, но возвращает число в байтах. Кана и распространённые иероглифы занимают в UTF-8 по 3 байта, поэтому в тексте целиком на японском позиция в байтах втрое больше позиции в символах, а в смешанном тексте они расходятся менее очевидно. mb_strpos() возвращает символы, а именно этого ждёт mb_substr().

Смешивать их это классическая ошибка: результат strpos(), переданный в mb_substr(), начинает слишком далеко от начала строки. Используйте strpos вместе с substr, а mb_strpos вместе с mb_substr.

Часто задаваемые вопросы

Что возвращает strpos() в PHP?

Позицию первого совпадения целым числом, считая с 0, или false, если игла не найдена. strpos('hello', 'l') возвращает 2.

Зачем нужно !== false со strpos()?

Потому что совпадение в самом начале возвращает 0, а 0 == false истинно. if (strpos($s, 'a')) считает совпадение на позиции 0 "не найденным". Всегда сравнивайте как strpos($s, 'a') !== false.

Чем отличаются strpos, stripos и strrpos?

strpos() находит первое совпадение и учитывает регистр. stripos() находит первое совпадение без учёта регистра. strrpos() находит последнее совпадение. strripos() находит последнее совпадение без учёта регистра.

Что использовать, чтобы проверить, содержит ли строка текст: strpos или str_contains?

В PHP 8 используйте str_contains($haystack, $needle): она возвращает простое true или false, и ловушки с позицией 0 у неё нет. strpos() берите, когда нужна сама позиция.

Как использовать strpos с японским или русским текстом?

strpos() правильно находит многобайтовый текст, но возвращает позицию в байтах. Если вы передаёте позицию в mb_substr() или показываете её пользователю, используйте mb_strpos(), она возвращает позицию в символах.

Иллюстрация языков программирования Coddy

Учитесь программировать с Coddy

НАЧАТЬ