PHP заменить строку в файле

PHP заменить строку в файле

Поиск и замена текста между тегами на PHP

Категория: Кодинг

Сегодня постараюсь объяснить как найти, обработать и заменить текст между тегами используя PHP функции. На первый взгляд простая задача, тем более в PHP есть специально предназначенные для этого функции, позволяющие использовать для поиска и замены регулярные выражения. Чтобы было проще разобраться, будем всё делать на примерах. За основу возьмем абстрактный html код.

… <xx>наташа</xx> … <xx>даша</xx> … <xx>настя</xx> …

Здесь <xx> — представляет какой-то конкретный html тег, а троеточие — другие произвольные теги. Предлагаю постепенно начинать разбираться с возможностями PHP по работе со строками. Все пункты будем рассматривать на примерах.

  • Поиск текста функцией «preg_match_all»
  • Перебор найденных результатов в цикле «foreach»
  • Отличие «preg_match» от «preg_match_all»
  • Замена текста между тегами функцией «preg_replace»
  • Замена тегов, оставляя всё, что внутри
  • Обработка и замена при помощи «preg_replace_callback»
  • Использование нумирации в заменах и другие продвинутые возможности

Поиск текста функцией «preg_match_all»

Для поиска текста внутри тегов воспользуемся функцией «preg_match_all». Зададим маску поиска и посмотрим, что она возвращает в качестве результата.

$sContent = «… <xx>наташа</xx> … <xx>даша</xx> … <xx>настя</xx> …»; if (preg_match_all(‘|<xx>(.+)</xx>|isU’, $sContent, $arr)) { echo $arr.» «.$arr.» «.$arr; echo «<br />»; echo $arr.» «.$arr.» «.$arr; } //на выходе получаем: //<xx>наташа</xx> <xx>даша</xx> <xx>настя</xx> //наташа даша настя

В нулевой разряд массива записались значения с тегами, а в первый — только текст между ними. Если требуется вывести все найденные результаты, то лучше использовать цикл foreach. Его рассмотрим ниже, а пока немного информации про функцию preg_match_all.

Она возвращает «1» в случае нахождения в тексте соответствия с указанной маской или «0», если соответствий не найдено. В качестве параметров функция принимает маску поиска, строковую переменную в которой будет осуществляться поиск и переменную типа двухмерный массив, в который будут записываться найденные совпадения.

|<xx>(.+)</xx>|isU

Маска поиска текста между тегов обрамляется символом «|». Таких правил в маске может быть несколько. Для нашей задачи достаточно одного.

В правиле содержатся теги, между которыми требуется заменить текст — «(.+)». Регулярное выражение указывает на то, что между ними может быть любое количество любых символов. Знак плюс означает что их должно быть больше нуля. То есть, если между тегами ничего нет, то результата никакого не получим. Если хотим найти даже те места, где между тегов нет текста, то вместо плюса ставим знак звёздочки — «*». Директива «isU» обозначает регистронезависимый поиск в многострочном тексте с кодировкой «UTF-8».

Обработка и замена при помощи «preg_replace_callback»

Переходим к самому интересному. Если нужно над найденным фрагметом произвести какие-то действия и только потом осуществить замену, то следует использовать «preg_replace_callback». Рассмотрим как с помощью этой функции в именах сделать первую букву заглавной.

<html> <head> <meta charset=»UTF-8″> </head> <body> <?php $sContent = «<xx>наташа</xx> … <xx>даша</xx> … <xx>настя</xx>»; echo htmlspecialchars($sContent); echo «<br />»; $sContent = preg_replace_callback(‘|(<xx>)(.+)(</xx>)|iU’, function($matches){ $matches = mb_substr(mb_strtoupper($matches, ‘UTF-8′),0,1,’UTF-8’).substr($matches, 2); return $matches.$matches.$matches; } ,$sContent); echo htmlspecialchars($sContent); ?> </body> </html>

В качестве параметров передаём маску поиска, функцию с кодом обработки и строковую переменную в которой осуществляем поиск. Дополнительно могут ещё быть заданы два необязательных параметра. О них в следующем разделе статьи.

Переменная «$matches» это массив, содержащий элементы регулярного выражения. В нулевом элементе будет содержаться вся исходная строка, а в остальных — содержимое скобок.

Код обработки не описываю, но отмечу что для замены первой буквы на заглавную я использую PHP функции для работы со строками в UTF-8 кодировке. Если у Вас кодировка cp1251, то нужно отбросить префикс «mb_» и удалить последний параметр у функций.

ВНИМАНИЕ! Код в примере будет работать только при использовании PHP версии 5.3 и выше. Для более поздних версий требуется доработка.

Использование нумирации в заменах и другие продвинутые возможности

Теперь немного о продвинутых возможностях функции «preg_replace_callback». Ранее я упоминал что у неё есть два необязательных параметра. Первый (по умолчанию равен «-1») содержит максимальное количество замен, которое должна произвести функция. Второй — переменная, в которую будет записано количество произведенных замен.

$sContent = preg_replace_callback(‘|(<xx>)(.+)(</xx>)|iU’, function($matches){ //тут код } ,$sContent,2,$count);

Задав эти два параметра в предыдущем примере, замена главной буквы будет произведена только у первых двух имён. Соответственно, переменная «$count» будет содержать — 2. Если установить первый дополнительный параметр в «-1», то «$count» будет — 3.

И в конце о том, как узнать какая по счету замена происходит в данный момент. Это может потребоваться если появилась необходимость произвести замену между пятым и десятым найденным элементом строки или требуется для каких-то тегов прописать уникальные идентификаторы.

Для реализации может быть использована глобальная или статическая переменная. Использование глобальных переменных может быть отключено в PHP, поэтому рассмотрим пример со статической переменной. Присвоим всем тегам h2 уникальный идентификатор.

<?php $str = ‘<h2>Марина</h2> <b>Алёша</b> <h2>Наташа</h2> <h2>Катя</h2>’; $str = preg_replace_callback(‘|<h2>(.+)</h2>|iU’, function($matches){ static $id = 0; $id++; return ‘<h2 id=»uniq-‘.$id.'»>’.$matches.'</h2>’; }, $str,-1,$count); echo $str.’ Количество замен: ‘.$count; ?>

Объявляя статическую переменную нужно помнить что она сохраняет своё значение между вызовами функции, поэтому идеально подходит для решения нашей задачи.

ВНИМАНИЕ! Дополнительные параметры в «preg_replace_callback» появились начиная с PHP версии 5.1


Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *