Инструменты замены текста в PHP: от простых до регулярных выражений
Основные подходы к замене подстрок в PHP
Как заменить все вхождения одной подстроки на другую?
str_replace - это встроенная функция PHP, выполняющая замену всех вхождений заданной строки (или массива строк) на другую строку (или массив). Она работает с обычными строками, без учёта регистра (чувствительна к регистру).
<?php
$original = 'Привет, мир! Мир прекрасен.';
$result = str_replace('мир', 'вселенная', $original);
echo $result; // Привет, вселенная! вселенная прекрасен.
?>
Привет, вселенная! вселенная прекрасен.
Функция принимает три обязательных параметра: что ищем, на что заменяем, исходная строка. Четвёртый необязательный параметр $count позволяет получить количество произведённых замен.
$text = 'раз раз раз';
$replaced = str_replace('раз', 'два', $text, $count);
echo 'Результат: ' . $replaced . ' (замен: ' . $count . ')';
Результат: два два два (замен: 3)
Типичная ошибка: Замена не происходит, если искомое значение не найдено, либо если перепутаны типы параметров. Функция ожидает строку или массив; передача числа может привести к неожиданному поведению (число будет преобразовано в строку).
Решение: Всегда явно приводить к строке значения, если они могут быть не строкового типа.
Как произвести замену без учёта регистра?
Функция str_ireplace работает идентично str_replace, но не чувствительна к регистру символов. Полезно, когда регистр исходного текста может варьироваться.
$text = 'PHP отличный язык. Php используется везде.';
$result = str_ireplace('php', 'JavaScript', $text);
echo $result;
JavaScript отличный язык. JavaScript используется везде.
Проблема: str_ireplace работает с однобайтовыми кодировками. Для многобайтовых (UTF-8) может давать некорректный результат для букв, состоящих из нескольких байтов (например, русские буквы «ё» и «е»).
Решение: Использовать mb_eregi_replace или mb_ereg_replace с флагом i (регистронезависимость) при работе с UTF-8.
Как заменить часть строки по позиции, а не по содержимому?
substr_replace позволяет заменить фрагмент строки, начиная с указанной позиции и заданной длины. Применяется для замены конкретного сегмента, когда известно его положение.
$str = 'abcdef';
// Заменить символы с позиции 1 длиной 2 на 'XYZ'
$result = substr_replace($str, 'XYZ', 1, 2);
echo $result; // aXYZdef
aXYZdef
Если длина не указана, заменяется всё до конца строки. Если начальная позиция отрицательна, отсчёт идёт с конца.
Типичная ошибка: Неверное указание длины или позиции, что приводит к замене не той части. Также нужно помнить, что substr_replace не обрабатывает многобайтовые символы корректно - лучше использовать mb_substr_replace.
Как заменить сложные шаблоны, включая регулярные выражения?
preg_replace выполняет замену по регулярному выражению. Это самый мощный, но и более ресурсоёмкий способ. Подходит для поиска по маске, замены с обратными ссылками, условной замены.
$text = 'Тел.: +7 (123) 456-78-90';
// Удалить все нецифровые символы, кроме +
$result = preg_replace('/[^\\d+]/', '', $text);
echo $result; // +71234567890
+71234567890
Проблема: Регулярные выражения сложны в отладке, могут быть медленными на больших строках. Ошибки в шаблоне (незакрытые скобки, неэкранированные символы) приводят к предупреждениям и отсутствию замены.
Решение: Использовать модификаторы (u для UTF-8, i для регистронезависимости). Проверять шаблон с помощью preg_match перед заменой.
Расширенные примеры замены строк в PHP
// Замена с массивами (попарная)
$search = array('cat', 'dog', 'bird');
$replace = array('кошка', 'собака', 'птица');
$text = 'I have a cat and a dog. The bird is flying.';
$result = str_replace($search, $replace, $text);
echo $result;
I have a кошка and a собака. The птица is flying.
// Использование strtr для замены по трансляции (быстрее при больших таблицах)
$trans = array('hello' => 'привет', 'world' => 'мир');
$text = 'hello world';
$result = strtr($text, $trans);
echo $result; // привет мир
привет мир
// Рекурсивная замена (замена до тех пор, пока вхождение не исчезнет)
function recursive_replace($search, $replace, $subject) {
$previous = '';
while ($previous !== $subject) {
$previous = $subject;
$subject = str_replace($search, $replace, $subject);
}
return $subject;
}
$text = 'aaa';
echo recursive_replace('aa', 'a', $text); // a (заменяет aa на a, затем a остается)
a
// Замена с помощью mb_ereg_replace для многобайтовых строк (UTF-8)
$text = 'Москва - столица России. Столица США - Вашингтон.';
$pattern = 'столица';
$replacement = 'главный город';
mb_regex_encoding('UTF-8');
$result = mb_ereg_replace($pattern, $replacement, $text);
echo $result;
// Москва - главный город России. главный город США - Вашингтон.
Москва - главный город России. главный город США - Вашингтон.
// Замена с ограничением количества (str_replace с count, но только общее количество; если нужно только N первых вхождений - применяем регулярное выражение или explode/implode)
$text = 'one one one one';
$parts = explode('one', $text, 3); // ограничиваем на 3 части
$result = implode('two', $parts);
echo $result; // two two one one (заменены только первые два вхождения, так как explode разбил на три части)
two two one one