- Поиск и замена текста между тегами на PHP
- Поиск текста функцией «preg_match_all»
- Перебор найденных результатов в цикле «foreach»
- Отличие «preg_match» от «preg_match_all»
- Замена текста между тегами функцией «preg_replace»
- Замена тегов, оставляя всё, что находится внутри
- Обработка и замена при помощи «preg_replace_callback»
- Использование нумирации в заменах и другие продвинутые возможности
- Наташа
- Катя
- (.+)
- '.$matches[1].'
- Поиск и замена текста между тегами в PHP
- Простая замена текста или тегов (preg_replace)
- Замена текста собственной функцией (preg_replace_callback)
- Вывод фрагментов исходного HTML и PHP кода
- Продвинутый BBCode с атрибутами
- Как вытащить строку между скобками
Поиск и замена текста между тегами на PHP
Рассмотрим примеры обработки и замены текста между HTML тегами, используя PHP функции для поиска и подмены по регулярным выражениям. Для примера возьмем абстрактный кусок кода, над которым будем проводить различные действия.
На месте может быть любой тег, а троеточие обозначает любой произвольный текст.
Поиск текста функцией «preg_match_all»
Для поиска текста внутри тегов воспользуемся функцией «preg_match_all». Зададим маску поиска и посмотрим, что она возвращает в качестве результата.
$sContent = ".наташа .даша .настя . "; if (preg_match_all('|(.+) |isU', $sContent, $arr)) < echo $arr[0][0] . " " . $arr[0][1] . " " . $arr[0][2] . "
"; echo $arr[1][0] . " " . $arr[1][1] . " " . $arr[1][2]; > //на выходе получаем: //наташа даша настя //наташа даша настя
В нулевой разряд массива записались значения с тегами, а в первый — только текст между ними. Если требуется автоматизировать вывод всего найденного, то лучше использовать цикл foreach . Его рассмотрим ниже.
Функция preg_match_all возвращает «1» в случае нахождения в тексте соответствия с указанной маской или «0», если соответствий не найдено. В качестве параметров принимает маску, строку где ищем и переменную, в которую будут записаны найденные совпадения.
Маска поиска обрамляется символами «|». За ними идут директивы — «isU» обозначает регистронезависимый поиск в многострочном тексте с кодировкой «UTF-8»
В самом правиле содержатся теги, между которыми требуется заменить текст — «(.+)». Точка символизирует любой символ, а плюс — что он может повторяться один или больше раз. Скобки говорят о том, что содержимое между ними нужно записать в переменную с результатом.
Перебор найденных результатов в цикле «foreach»
Для вывода результатов поиска можно воспользоваться циклом «foreach».
$sContent = ".Наташа .Марина .Настя . "; if (preg_match_all('|(.+) |isU', $sContent, $arr)) < foreach ($arr[0] as $value) echo $value." "; echo "
"; foreach ($arr[1] as $value) echo $value." "; >
На выходе получаем тоже самое что и в предыдущем примере, зато теперь мы автоматизировали перебор массива и сократили код.
Отличие «preg_match» от «preg_match_all»
Функция «preg_match» осуществляет поиск только до первого соответсвия с маской. Как только что-то найдено — поиск останавливается и возвращается одномерный массив.
if (preg_match('||isU', $sContent, $arr)) return $arr[1]; else return false;
Здесь нулевой элемент массива «$arr» содержит найденное совпадение вместе с тегами «title», а первый элемент — «$arr[1]» только текст между этими тегами. Если в строке несколько тегов «title», это не значит что остальные значения будут записаны в «$arr[2]» и так далее. Элемент «$arr[2]» окажется не пуст если в маске указано несколько правил, но об этом в следующий раз.
Замена текста между тегами функцией «preg_replace»
Если требуется найти и произвести замену найденных элементов в строке, то на помощь приходит PHP функция «preg_replace».
Заменим в нашем примере все имена между тегами на какое-то конкретное, например — «Оля».
$sContent = "наташа .даша .настя "; $sContent = preg_replace('|().+( )|isU', "$1"."Оля"."$2",$sContent);
Замена тегов, оставляя всё, что находится внутри
А теперь небольшой пример, показывающий как заменить определенные теги, сохранив содержимое между ними. Допустим, надо изменить в html коде все «strong» на CSS форматирование.
$sContent = ". Настя . "; $sContent = preg_replace('||isU', '', $sContent); //на выходе получаем $sContent: //. Настя .
Обработка и замена при помощи «preg_replace_callback»
Переходим к самому интересному. Если нужно над найденным фрагметом произвести какие-то действия и только потом осуществить замену, то следует использовать «preg_replace_callback». Рассмотрим как с помощью этой функции в именах сделать первую букву заглавной.
наташа .даша .настя "; echo htmlspecialchars($sContent); echo "
"; $sContent = preg_replace_callback('|()(.+)( )|iU', function($matches) < $matches[2] = mb_substr(mb_strtoupper($matches[2], 'UTF-8'),0,1,'UTF-8').substr($matches[2], 2); return $matches[1].$matches[2].$matches[3]; >,$sContent); echo htmlspecialchars($sContent); ?>
В качестве параметров передаём маску поиска, функцию с кодом обработки и строковую переменную в которой осуществляем поиск. Дополнительно могут ещё быть заданы два необязательных параметра. О них в следующем разделе статьи.
Переменная «$matches» это массив, содержащий элементы регулярного выражения. В нулевом элементе будет содержаться вся исходная строка, а в остальных — содержимое скобок.
Код обработки не описываю, но отмечу что для замены первой буквы на заглавную я использую PHP функции для работы со строками в UTF-8 кодировке. Если у Вас кодировка cp1251, то нужно отбросить префикс «mb_» и удалить последний параметр у функций.
ВНИМАНИЕ! Код в примере будет работать только при использовании PHP версии 5.3 и выше. Для более поздних версий требуется доработка.
Использование нумирации в заменах и другие продвинутые возможности
Теперь немного о продвинутых возможностях функции «preg_replace_callback». Ранее я упоминал что у неё есть два необязательных параметра. Первый (по умолчанию равен «-1») содержит максимальное количество замен, которое должна произвести функция. Второй — переменная, в которую будет записано количество произведенных замен.
$sContent = preg_replace_callback('|()(.+)( )|iU', function($matches) < //тут код >,$sContent,2,$count);
Задав эти два параметра в предыдущем примере, замена главной буквы будет произведена только у первых двух имён. Соответственно, переменная «$count» будет содержать — 2. Если установить первый дополнительный параметр в «-1», то «$count» будет — 3.
И в конце о том, как узнать какая по счету замена происходит в данный момент. Это может потребоваться если появилась необходимость произвести замену между пятым и десятым найденным элементом строки или требуется для каких-то тегов прописать уникальные идентификаторы.
Для реализации может быть использована глобальная или статическая переменная. Использование глобальных переменных может быть отключено в PHP, поэтому рассмотрим пример со статической переменной. Присвоим всем тегам h2 уникальный идентификатор.
Марина АлёшаНаташа
Катя
'; $str = preg_replace_callback('|(.+)
|iU', function($matches)< static $id = 0; $id++; return ''.$matches[1].'
'; >, $str,-1,$count); echo $str.' Количество замен: '.$count; ?>
Объявляя статическую переменную нужно помнить что она сохраняет своё значение между вызовами функции, поэтому идеально подходит для решения нашей задачи.
Поиск и замена текста между тегами в PHP
И из него нужно достать текст, который находится между тегами и .
Проще всего это сделать с помощью регулярных выражений:
$text = 'Ищем эту и может быть эту строки в тексте.
'; if(preg_match_all('|(.*)|Uis', $text, $result)) < foreach($result[1] as $span_text) echo $span_text . '
'; > else echo 'Совпадений нет';
Функция preg_match_all() принимает 3 параметра: шаблон поиска, сам текст и переменную, в которую эта функция сохранит результаты поиска.
Поскольку функция возвращает количество найденных строк (или false в случае ошибки), мы можем сразу подставить её в оператор if.
Массив с результатами поиска (в нашем случае $result) состоит из двух частей: в $result[0] будут найденные строки вместе с открывающим и закрывающим тегами span, а в $result[1] будут те же строки без тега span, т.е. тот текст, что находится в круглых скобках.
Маска регулярного выражения находится между вертикальными чертами | . В шаблоне (.*) точка означает любой символ, звёздочка — любое количество символов (т.е. суммарно получаем «любое количество любых символов»).
Скобки говорят, что найденный текст нам нужно получить отдельно. Без скобок мы получим только $result[0], а $result[1] не будет существовать.
Чтобы найти только не пустые теги, можно заменить .* на .+ . Плюсик означает любое количество символов, но не меньше одного.
Uis — модификаторы. U означает работу с UTF-8, i — регистронезависимый поиск, s — что символ точка включает в себя переносы строк, т.е. поиск будет по всем строкам, а не по одной.
Простая замена текста или тегов (preg_replace)
Заменить текст без замены тегов можно следующим образом:
$text = 'Строки один и два в тексте.
'; $new_text = preg_replace('|().*()|Uis', '$1три$2', $text); echo $new_text; // Выведет: Строки три и три в тексте.
$1 и $2 содержат открывающий и закрывающий теги соответственно, поскольку мы поместили их в скобки.
А в следующем примере меняются только теги, сам текст остаётся нетронутым:
Строки один и два в тексте.'; $new_text = preg_replace('|(.*)()|Uis', '$1', $text); echo $new_text; // Строки один и два в тексте.
Замена текста собственной функцией (preg_replace_callback)
Самое вкусное. Допустим, мы хотим использовать на сайте что-то вроде BBCode, т.е. собственные теги, которые потом должны заменяться на обычный HTML код:
Заменить тег на обычный HTML тег можно так:
Заголовок