(.+)

Поиск и замена текста между тегами на 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», если соответствий не найдено. В качестве параметров принимает маску, строку где ищем и переменную, в которую будут записаны найденные совпадения.

Читайте также:  Вывод php на jquery

Маска поиска обрамляется символами «|». За ними идут директивы — «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 тег можно так:

Заголовок

'; $new_text = preg_replace_callback('|

(.*)

|Uis', function($matches) < return '

' . $matches[1] . '

'; >, $text); echo $new_text;

Функция preg_replace_callback передаёт каждую найденную строку в нашу безымянную функцию, затем заменяет найденный текст на то, что наша функция возвращает.

Не знаком с безымянными функциями? Тогда можно сделать так:

function replaceH1($matches) < return '

' . $matches[1] . '

'; > $text = '

Заголовок

'; $new_text = preg_replace_callback('|

(.*)

|Uis', 'replaceH1', $text); echo $new_text;

Вторым параметром передаём название нашей функции. Код отработает точно также, как и предыдущий.

Вывод фрагментов исходного HTML и PHP кода

Частая проблема разработчиков, которым хочется вести свой блог. Есть HTML статья, внутри которой некоторые фрагменты кода нужно прогонять через htmlspecialchars() , чтобы они выводились как обычный текст:

$text =' 

Пример кода

Этот текст не должен быть жирным

Какое-то описание кода выше.

Второй не жирный текст ';

Теперь в этом нет ничего сложного:

$text = ' 

Пример кода

Этот текст не должен быть жирным

Какое-то описание кода выше.

Второй не жирный текст '; $new_text = preg_replace_callback('|(.*)|Uis', function($matches) < return htmlspecialchars($matches[1], ENT_QUOTES, 'UTF-8'); >, $text); echo $new_text;

Продвинутый BBCode с атрибутами

Иногда описанного выше функционала бывает недостаточно, например если нужно передать в функцию какие-либо параметры:

Вместо собственного велосипеда рекомендую использовать готовую библиотеку Shortcode.

В ней из коробки уже есть возможность использования атрибутов, а также события и куча других полезных фишек. Вот как может выглядеть пример обработки тега с атрибутами:

use Thunder\Shortcode\ShortcodeFacade; $text = 'текст с тегами'; $shortcode = new ShortcodeFacade(); $shortcode->addHandler('link', function($s) < $content = $s->getContent(); $url = $s->getParameter('url'); $title = $s->getParameter('title'); if(!$title) $title = 'Стандартный заголовок'; // Ещё какие-нибудь действия return $content; >); $new_text = $shortcode->process($text);

Только нужно учесть, что в Shortcode по-умолчанию парсятся атрибуты в квадратных скобках [] . Я и сам использую квадратные, но в примерах использовал фигурные, чтобы избежать возможных конфликтов тегов на этом сайте.

Источник

Как вытащить строку между скобками

Как вытащить строку между ковычек
Здравствуйте. Начал знакомиться с preg_match, но никак не могу справиться с задачей, нужно вытащить.

Как вытащить строку между двумя словами?
Между словом Referer: и словом \r\n

Удалите из строки последовательности символов, расположенные между круглыми скобками вместе со скобками
Удалите из строки последовательности символов, расположенные между круглыми скобками вместе со.

ЦитатаСообщение от Sergio Aguero Посмотреть сообщение

ЦитатаСообщение от DrobyshevAlex Посмотреть сообщение

 $str = 'sd34 w (3r3w w 33w 3w w[]w33*0.,/])3kl3f'; preg_match('/\((.+)\)/', $str, $m); echo $m[1];

ЦитатаСообщение от DrobyshevAlex Посмотреть сообщение

я с этим как то игрался) только у меня теги были, слегка переделал под скобки, но скобки он видит не только как символы но еще и как скобки, чтоб брать из них, поэтому надо первый, а не нулевой эл-т брать)

1 2 3 4 5 6 7 8 9 10 11 12 13
$std=" (text ( sektext ) ff)"; echo htmlspecialchars( $std); $re10 = '|\( (.*)\) |xs'; preg_match($re10,$std,$pockets3) or die("No tegs"); echo "
"; print_r( $pockets3); echo "

"; $re10 = '|.*\( (.*?)\) |xs'; preg_match($re10,$std,$pockets3) or die("No tegs"); echo "

"; print_r( $pockets3); echo "

";

в первом случае он берет содержимое содержимое внешних скобок, а во втором стгоит знак ? который уменьшает жадность точки)

Источник

Оцените статью