Поиск фрагмента текста: все функции PHP для строк

Раздел: Программирование на PHP -> Поиск и фильтрация данных

Основные способы поиска подстроки в PHP

Какая функция PHP для поиска подстроки самая быстрая и простая?

str_contains() (PHP 8.0+) – наиболее эффективное и интуитивно понятное решение. Она возвращает true, если подстрока присутствует, и false в противном случае. Пример:


$str = 'Программирование на PHP';
$sub = 'PHP';
if (str_contains($str, $sub)) {
    echo 'Подстрока найдена';
}
  

Php поиск в строке (поиск подстроки в строке php)

Для версий PHP ниже 8.0 рекомендуется strpos(). Она возвращает позицию первого вхождения (int) или false, если подстрока не найдена. Важно использовать строгое сравнение (===) для проверки:


$pos = strpos($str, $sub);
if ($pos !== false) {
    echo "Найдено на позиции $pos";
}
  

Какие ошибки возникают при работе со strpos и как их избежать?

  • Забывают строгое сравнение: if ($pos != false) не сработает, если подстрока в начале строки (позиция 0). Всегда используйте if ($pos !== false).
  • Регистрозависимость: strpos учитывает регистр символов. Для регистронезависимого поиска используйте stripos().
  • Проблемы с многобайтовыми кодировками (UTF-8): strpos работает с байтами, а не с символами. Для корректной работы используйте mb_strpos().

Как выполнить регистронезависимый поиск?

Используйте stripos() – аналог strpos, игнорирующий регистр. Пример:


$haystack = 'Встреча в Москве';
$needle = 'москве';
if (stripos($haystack, $needle) !== false) {
    echo 'Найдено независимо от регистра';
}
  

Как найти последнее вхождение подстроки?

strrpos() возвращает позицию последнего вхождения. Для регистронезависимого – strripos(). Пример:


$str = 'PHP – это PHP';
$pos = strrpos($str, 'PHP');
echo $pos; // 13
  
Как получить часть строки до или после подстроки?

strstr() находит первое вхождение и возвращает все от него до конца строки. stristr() – регистронезависимая версия. Если третий параметр true, возвращается часть до подстроки:


$email = 'user@example.com';
$domain = strstr($email, '@'); // '@example.com'
$username = strstr($email, '@', true); // 'user'
  
Как подсчитать количество вхождений подстроки?

substr_count() возвращает целое число – сколько раз подстрока встречается. Учитывает только неперекрывающиеся вхождения.


$text = 'раз два раз два раз';
$count = substr_count($text, 'раз');
echo $count; // 3
  

Как искать подстроку с помощью регулярных выражений?

Функция preg_match() позволяет использовать сложные шаблоны. Она возвращает 1, если найдено совпадение, и 0 в противном случае. Пример – поиск email в тексте:


$str = 'Контакты: support@php.net';
$pattern = '/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/';
if (preg_match($pattern, $str, $matches)) {
    echo 'Найден email: ' . $matches[0];
}
  

Типичные ошибки:

  • Не экранировать специальные символы (точка, слэш и т.д.) – используйте preg_quote().
  • Забывать про модификаторы (u для UTF-8, i для регистронезависимости).
  • Для многобайтовых строк setlocale может повлиять на поведение шаблонов.

Как корректно искать подстроку в UTF-8 строках?

Для UTF-8 и других многобайтовых кодировок используйте функции из модуля mbstring: mb_strpos(), mb_stripos() и mb_strstr(). Они работают с символами, а не с байтами. Пример:


$text = 'Привет, мир!';
$pos = mb_strpos($text, 'мир');
echo $pos; // 8 (позиция в символах)
  

Расширенные примеры поиска подстроки

Как использовать strpos с указанием начальной позиции поиска?

Пример

$str = 'PHP - это язык PHP';
$first = strpos($str, 'PHP'); // 0
$second = strpos($str, 'PHP', $first + 1); // 18
echo "Первое вхождение: $first, второе: $second";
  
Первое вхождение: 0, второе: 18
  

Как найти все позиции подстроки в строке, используя цикл?

Пример

$str = 'ab aba abab';
$needle = 'ab';
$offset = 0;
$positions = [];
while (($pos = strpos($str, $needle, $offset)) !== false) {
    $positions[] = $pos;
    $offset = $pos + 1;
}
print_r($positions);
  
Array
(
    [0] => 0
    [1] => 3
    [2] => 6
    [3] => 8
)
  

Обратите внимание: перекрывающиеся подстроки (например, 'aba' содержит 'ab' дважды на позициях 0 и 1) не будут найдены таким способом, так как offset каждый раз сдвигается на 1.

Как с помощью preg_match_all найти все совпадения с шаблоном и их позиции?

Пример

$str = 'Цена: 100 руб, скидка: 20%';
$pattern = '/(\d+)/';
preg_match_all($pattern, $str, $matches, PREG_OFFSET_CAPTURE);
foreach ($matches[0] as $match) {
    echo "Число: {$match[0]}, позиция: {$match[1]}\n";
}
  
Число: 100, позиция: 6
Число: 20, позиция: 19
  

Как получить часть строки до указанной подстроки, используя explode?

Пример

$path = '/var/www/html/index.php';
$parts = explode('/', $path);
echo $parts[0]; // ''
  

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

Как искать подстроку, игнорируя HTML-теги (только текст)?

Пример

$html = '

Привет, мир!

'; $text = strip_tags($html); if (str_contains($text, 'мир')) { echo 'Найдено в тексте без тегов'; }

Важно: strip_tags может удалить не все нежелательные символы, для точной работы с HTML используйте DOMDocument.

Как сравнивать производительность разных методов поиска?

Пример

$str = str_repeat('a', 10000) . 'b';
$needle = 'b';
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    str_contains($str, $needle);
}
echo 'str_contains: ' . (microtime(true) - $start) . " сек\n";

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    strpos($str, $needle);
}
echo 'strpos: ' . (microtime(true) - $start) . " сек\n";
  
str_contains: 0.004 сек
strpos: 0.005 сек
  

На практике разница незначительна, но str_contains читается лучше.

Поиск подстроки в строке PHP - comments

En
Php поиск в строке (php)