Основные приёмы обработки строк
Как определить длину текстовой строки?
Для однобайтовых кодировок используется функция strlen(), которая возвращает количество байт. В многобайтовых (например, UTF-8) применяется mb_strlen() с указанием кодировки. Это основной рекомендуемый способ.
Альтернативы: iconv_strlen() для кодировок iconv; разбиение строки на массив с помощью preg_split('//u', $str, -1, PREG_SPLIT_NO_EMPTY) и последующий подсчёт элементов через count(), но это менее эффективно.
Типичная ошибка - путаница между байтами и символами в UTF-8. Использование strlen() для кириллицы даёт число, вдвое превышающее реальное количество символов. Решение: всегда применять mb_strlen() для текстов с не-ASCII символами. Цель: подсчёт символов, ограничение длины, валидация.
$str = "Привет, мир!";
echo strlen($str); // 21 (в UTF-8 кириллица 2 байта)
echo mb_strlen($str, 'UTF-8'); // 12
Как найти позицию первого вхождения подстроки?
Функция strpos($haystack, $needle) - самый быстрый способ для однобайтовых строк. Для многобайтовых используйте mb_strpos($haystack, $needle, 0, 'UTF-8'). Обязательно строгое сравнение с false через ===.
Варианты: preg_match() для поиска по регулярному выражению; substr() в цикле; strpbrk() для поиска набора символов.
Ошибка: strpos может вернуть 0, что при нестрогом сравнении (==) интерпретируется как false. Всегда используйте ===. Цель: проверка наличия подстроки, извлечение контекста.
$text = "Hello world";
$pos = strpos($text, 'world');
if ($pos !== false) { echo "Найдено на позиции $pos"; }
Как заменить одну подстроку на другую?
str_replace($search, $replace, $subject) - простая и быстрая замена, работает со строками и массивами. Для регистронезависимой замены используйте str_ireplace().
Альтернативы: preg_replace() для замен по регулярным выражениям (например, удаление лишних пробелов); strtr() для таблицы замен; substr_replace() для замены в указанной позиции.
str_replace заменяет все вхождения. Для замены только первого вхождения используйте preg_replace с лимитом или substr_replace. В preg_replace требуется экранирование специальных символов. Цель: очистка текста, форматирование, замена шаблонов.
$text = "яблоко, банан, яблоко";
$new = str_replace('яблоко', 'апельсин', $text);
echo $new; // апельсин, банан, апельсин
Как разбить строку на массив по разделителю?
explode($delimiter, $string) - быстрый способ для фиксированного разделителя. Работает на уровне байт, поэтому безопасен для любых кодировок.
Варианты: preg_split() для разделителя-регулярного выражения (например, по пробелам или запятым с пробелами); str_split() для разбиения по количеству символов; sscanf() для разбора форматированной строки.
explode не поддерживает регулярные выражения. Пустой разделитель вызывает ошибку. preg_split может быть медленнее при простых разделителях. Цель: парсинг CSV, токенизация.
$csv = "один, два, три";
$arr = explode(', ', $csv);
print_r($arr); // Array ( [0] => один [1] => два [2] => три )
Как объединить элементы массива в строку с разделителем?
implode($glue, $pieces) - стандартный способ. Алиас join(). Добавляет разделитель между элементами, но не после последнего.
Альтернативы: конкатенация в цикле с проверкой на последний элемент; sprintf() для форматирования; array_reduce() для произвольной логики.
При конкатенации в цикле часто возникает лишний разделитель в конце. implode решает эту проблему. Цель: формирование CSV, SQL-списков, URL-параметров.
$fruits = ['яблоко', 'банан', 'вишня'];
echo implode(', ', $fruits); // яблоко, банан, вишня
Как удалить пробелы в начале и конце строки?
trim() удаляет пробельные символы с обеих сторон, ltrim() слева, rtrim() справа. По умолчанию удаляются пробелы, табуляция, переносы строк.
Можно использовать preg_replace('/^\s+|\s+$/u', '', $str) для точного контроля. strip_tags() не предназначен для удаления пробелов.
trim() не удаляет неразрывные пробелы (nbsp, Unicode U+00A0). Для их удаления укажите символы вручную: trim($str, " \t\n\r\0\x0B\xC2\xA0"). Цель: очистка ввода пользователя.
$str = " Привет! ";
echo trim($str); // Привет!
Как преобразовать текст в нижний или верхний регистр?
Для однобайтовых строк используйте strtolower() и strtoupper(). Для UTF-8 обязательно применять mb_strtolower() и mb_strtoupper(). ucfirst() и ucwords() для заглавных первых букв.
Варианты: mb_convert_case() с опцией MB_CASE_TITLE; strtr() с таблицей замен.
Стандартные strtolower и strtoupper искажают кириллицу и другие не-ASCII символы (работают только с английским). Всегда используйте mb_* для многобайтовых строк. Цель: нормализация текста, сравнение без учёта регистра.
$text = "Привет МИР!";
echo strtolower($text); // искажение
echo mb_strtolower($text, 'UTF-8'); // привет мир!
Как сравнить две строки с учётом регистра?
strcmp($str1, $str2) - бинарно безопасное сравнение, возвращает 0 при равенстве. Для сравнения без учёта регистра - strcasecmp(). Для UTF-8 используйте strcoll() с установленной локалью или mb_strcasecmp (если доступен).
Альтернативы: strpos() для проверки вхождения; similar_text() для оценки схожести в процентах; levenshtein() для расстояния редактирования.
Стандартные strcmp и strcasecmp работают с однобайтовыми строками. Для многобайтовых результат может быть неверным. strcoll зависит от локали. Для безопасного сравнения паролей используйте hash_equals(). Цель: сортировка, проверка равенства.
$a = "abc"; $b = "ABC";
echo strcmp($a, $b); // >0
echo strcasecmp($a, $b); // 0
Расширенные примеры работы с текстом
Как извлечь все email-адреса из текста с помощью регулярных выражений?
Пример
$text = "Контакты: info@example.com, support@test.org.";
preg_match_all('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/', $text, $matches);
print_r($matches[0]);
Array
(
[0] => info@example.com
[1] => support@test.org
)
Функция preg_match_all находит все совпадения с шаблоном. Регулярное выражение охватывает типичные email, но не учитывает все возможные домены верхнего уровня. Для более точного валидации применяются специализированные библиотеки.
Как разбить строку на слова с учётом юникода и знаков препинания?
Пример
$str = "Привет, мир! Как дела?";
$words = preg_split('/[\s\p{P}]+/u', $str, -1, PREG_SPLIT_NO_EMPTY);
print_r($words);
Array
(
[0] => Привет
[1] => мир
[2] => Как
[3] => дела
)
Модификатор u включает поддержку юникода. Класс \p{P} обозначает все знаки пунктуации. PREG_SPLIT_NO_EMPTY удаляет пустые элементы. Этот способ надёжнее explode при нестандартных разделителях.
Как преобразовать кириллическую строку в транслит (slug) для URL?
Пример
$trans = array(
'а'=>'a','б'=>'b','в'=>'v','г'=>'g','д'=>'d','е'=>'e','ё'=>'yo','ж'=>'zh',
'з'=>'z','и'=>'i','й'=>'y','к'=>'k','л'=>'l','м'=>'m','н'=>'n','о'=>'o',
'п'=>'p','р'=>'r','с'=>'s','т'=>'t','у'=>'u','ф'=>'f','х'=>'kh','ц'=>'ts',
'ч'=>'ch','ш'=>'sh','щ'=>'shch','ъ'=>'','ы'=>'y','ь'=>'','э'=>'e','ю'=>'yu','я'=>'ya'
);
$text = "Привет, мир! Как дела?";
// Приводим к нижнему регистру с учётом UTF-8
$slug = mb_strtolower($text, 'UTF-8');
// Заменяем символы согласно таблице
$slug = str_replace(array_keys($trans), array_values($trans), $slug);
// Удаляем всё, кроме букв латиницы, цифр и пробелов
$slug = preg_replace('/[^a-z0-9\s]/u', '', $slug);
// Заменяем пробелы на дефис
$slug = preg_replace('/\s+/u', '-', $slug);
echo $slug; // privet-mir-kak-dela
privet-mir-kak-dela
Таблица транслитерации упрощённая. Для реальных проектов рекомендуется использовать проверенные библиотеки или официальные стандарты (ISO 9).
Как переформатировать дату из формата ISO в европейский с помощью обратной ссылки?
Пример
$date = "2025-03-12";
$formatted = preg_replace('/(\d{4})-(\d{2})-(\d{2})/', '$3.$2.$1', $date);
echo $formatted; // 12.03.2025
12.03.2025
В шаблоне используются захватывающие группы (\d{4}). В строке замены $3.$2.$1 обратные ссылки ($1, $2, $3) подставляют захваченные значения. Этот приём удобен для изменения порядка частей даты или других структурированных строк.