Методы обработки текста на PHP: от регулярных выражений до работы с файлами
Основные задачи обработки текста
Наиболее эффективное решение для разбора текстового файла и вывода его содержимого с минимальными затратами памяти - использование функции file(). Она считывает файл в массив строк, что удобно для дальнейшей построчной обработки.
Пример: файл text.txt содержит строки с данными. Вывод каждой строки с номером.
$lines = file('text.txt', FILE_IGNORE_NEW_LINES);
foreach ($lines as $num => $line) {
echo "Строка " . ($num + 1) . ": " . htmlspecialchars($line) . "<br>";
}
Index php text (работа с текстовыми данными на php)
Строка 1: Привет мир Строка 2: Текст для обработки Строка 3: PHP работает с файлами
Возможные ошибки: файл может отсутствовать или быть недоступным для чтения. В таких случаях file() возвращает false и генерирует предупреждение. Рекомендуется проверять результат: if ($lines === false) { ... }. Также при работе с большими файлами (сотни мегабайт) массив может занять много памяти, тогда лучше использовать построчное чтение через fopen/fgets.
Как загрузить большой текстовый файл без полной загрузки в память?
Использование пары fopen() и fgets() позволяет читать строку за строкой, экономя оперативную память.
$handle = fopen('bigfile.txt', 'r');
if ($handle) {
while (($line = fgets($handle)) !== false) {
echo $line . "<br>";
}
fclose($handle);
}
Проблема: после чтения файла ресурс открыт, его необходимо закрыть. Если забыть вызов fclose(), может возникнуть утечка ресурсов. Также стоит проверять, что fopen() не вернула false.
Как выполнить поиск и замену текста с учётом регистра?
Функция str_ireplace() (регистронезависимая замена) или комбинация str_replace() с предварительным приведением строк.
$text = 'Привет мир, Мир большой.';
$search = 'мир';
$replace = 'земля';
$result = str_ireplace($search, $replace, $text);
echo $result;
Привет земля, земля большой.
Ошибка: в мультибайтовых кодировках (например, UTF-8) str_ireplace() может работать некорректно из-за того, что она однобайтовая. Для кириллицы и других многобайтных языков следует использовать mb_eregi_replace() или mb_strtolower() вместе с str_replace().
Как разбить текст на массив слов?
Использование explode() для разделения по пробелу, но лучше preg_split() для учёта множественных пробелов и знаков препинания.
$text = 'Я изучаю PHP, это интересно!';
$words = preg_split('/[\s,!\.]+/', $text, -1, PREG_SPLIT_NO_EMPTY);
print_r($words);
Array
(
[0] => Я
[1] => изучаю
[2] => PHP
[3] => это
[4] => интересно
)
Проблема: при использовании explode() с одним разделителем можно пропустить слова, разделённые несколькими пробелами. Также не учитываются знаки препинания. Регулярное выражение решает эти вопросы, но требует внимательного составления шаблона.
Как безопасно вывести текст, полученный от пользователя?
Функция htmlspecialchars() преобразует специальные символы в HTML-сущности, предотвращая XSS-атаки. Также можно удалить лишние пробелы trim().
$input = "<script>alert('XSS')</script>";
$safe = htmlspecialchars($input, ENT_QUOTES, 'UTF-8');
echo $safe;
<script>alert('XSS')</script>
Ошибка: забыть применить htmlspecialchars() перед выводом - распространённая уязвимость. Также важно указывать кодировку (UTF-8), иначе символы могут отображаться некорректно.
Как работать с кириллицей и другими многобайтными кодировками?
Использование функций модуля mb_string (Multibyte String): mb_strtolower(), mb_substr(), mb_strlen(). Без них операции со строками дают неверные результаты.
$text = 'Привет, Мир!';
echo mb_strlen($text, 'UTF-8') . "<br>"; // 12
echo strlen($text) . "<br>"; // 19 (ошибочно)
12 19
Проблема: strlen() считает количество байт, а не символов. Для UTF-8 каждый кириллический символ занимает 2 байта. Это приводит к ошибкам при обрезании строк или сравнении. Всегда использовать mb_* функции с указанием кодировки.
Расширенные примеры обработки текста
Извлечение email-адресов из текста с помощью регулярного выражения
Регулярное выражение для поиска email: /[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/. Функция preg_match_all() находит все совпадения.
$text = 'Контакты: support@example.com и info@site.org. Также admin@test.co.uk.';
preg_match_all('/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}/', $text, $matches);
print_r($matches[0]);
Array
(
[0] => support@example.com
[1] => info@site.org
[2] => admin@test.co.uk
)
Пояснение: preg_match_all помещает результат в многомерный массив, где $matches[0] содержит все полные совпадения. Регулярное выражение можно усложнить для более строгой проверки, но оно уже покрывает большинство реальных адресов.
Преобразование обычного текста в HTML с абзацами
Разделить текст на абзацы по двойному переносу строки и обернуть каждый в <p>.
$text = "Первая часть текста.\n\nВторая часть.\nЕще строка во втором абзаце.\n\nТретий абзац.";
$paragraphs = explode("\n\n", $text);
$html = '';
foreach ($paragraphs as $p) {
$p = trim($p);
if ($p !== '') {
$html .= "<p>" . nl2br(htmlspecialchars($p)) . "</p>\n";
}
}
echo $html;
<p>Первая часть текста.</p> <p>Вторая часть.<br> Еще строка во втором абзаце.</p> <p>Третий абзац.</p>
Пояснение: explode по двум переводам строк отделяет абзацы. Затем каждый абзац обрамляется <p>, а одиночные переводы строк заменяются на <br> через nl2br(). Экранирование через htmlspecialchars предотвращает внедрение HTML.
Замена BBCode-тегов на HTML
Пример простого парсера BBCode: [b]текст[/b] в <strong>.
$bbcode = '[b]Жирный текст[/b] и [i]курсив[/i]';
$find = ['/\[b\](.*?)\[\/b\]/s', '/\[i\](.*?)\[\/i\]/s'];
$replace = ['<strong>$1</strong>', '<em>$1</em>'];
$html = preg_replace($find, $replace, $bbcode);
echo $html;
<strong>Жирный текст</strong> и <em>курсив</em>
Пояснение: Используются модификаторы s (точка включает перевод строки) и нежадный квантификатор *?. Замена происходит через обратные ссылки $1. Для более сложных BBCode (списки, ссылки) можно расширить массивы.
Обработка CSV-строки с экранированными полями
Встроенная функция str_getcsv() парсит строку CSV с учётом кавычек и разделителей.
$csv = 'Иван,Петров,"Москва, ул. Ленина",30';
$data = str_getcsv($csv);
print_r($data);
Array
(
[0] => Иван
[1] => Петров
[2] => Москва, ул. Ленина
[3] => 30
)
Пояснение: str_getcsv() автоматически обрабатывает экранированные запятые внутри кавычек. Разделитель по умолчанию запятая, но можно указать другой через второй параметр.
Транслитерация кириллицы в латиницу
Преобразование русских символов в латинские эквиваленты для URL или имён файлов.
function transliterate($text) {
$map = [
'а' => '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 = mb_strtolower($text, 'UTF-8');
return strtr($text, $map);
}
echo transliterate('Привет, как дела?');
privet,_kak_dela?
Пояснение: Функция переводит текст в нижний регистр, затем заменяет каждый символ согласно массиву. Пробел заменяется на подчёркивание. Для полной транслитерации можно добавить обработку заглавных букв, но пример демонстрирует базовый подход.