Работаю в PHP. Нужно заменить все ссылки, в которых присутствует расширение jpg, png и т.д. Делаю так:
$row["message"] = preg_replace('/<a\shref=\"(.+?[jpeg|jpg|png])\"\starget=\"_blank\">(.+?)<\/a>/is', '<a data-fancybox="gallery" href="$1"><img src="$1" alt="" class="tmp_class"></a>', $row["message"]);
Для тестирования следующая строка:
<p>С этой формы приходят заявки <a href="https://site.com/lack_tech.php">https://site.com/lack_tech.php</a></p>
<p>Или что ты имеешь ввиду?</p>
<div class="attachment_files_message">
<p>Прикреплённые файлы:</p>
<a href="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png" target="_blank">Screenshot_1.png</a>
</div>
То есть нужно заменить вторую ссылку, а по моему коду, заменяется все что между началом ссылки <a href="....
и до самого последнего концевого тега </a>
Шаблон [jpeg|jpg|png]
идентичен [jegnp|]
, так как [...]
— это символьный класс, который находит 1 символ из указанных в классе. Кроме того, .+?
может захватить слишком много текста, так как точка находит любой символ.
Если заменить \"(.+?[jpeg|jpg|png])\"
на "([^"]*\.(?:jpe?g|png))"
, ошибка исчезнет, однако в некоторых случаях это выражение всё равно не сработает (разное количество пробельных символов, отсутствие или расположение в другом месте атрибута target=\"_blank\"
).
Решение на основе DOMDocument
представляется более уместным в таком случае.
См. демо на PHP:
$html = <<<EOD
<p>С этой формы приходят заявки <a href="https://site.com/lack_tech.php">https://site.com/lack_tech.php</a></p>
<p>Или что ты имеешь ввиду?</p>
<div class="attachment_files_message">
<p>Прикреплённые файлы:</p>
<a href="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png" target="_blank">Screenshot_1.png</a>
</div>
EOD;
$dom = new DOMDocument(); // Создаем DOM
$dom->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8'), LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Парсим DOM
$xpath = new DOMXPath($dom); // Инициализируем структуру XPath на основе DOM
foreach ($xpath->query('//a[@target="_blank"]') as $OurNode) {
if (preg_match('~\.(?:jpe?g|png)$~i', $OurNode->getAttribute('href'))) {
$fragment = $dom->createDocumentFragment();
$aNode = $dom->createElement('a');
$aNode->setAttribute('data-fancybox', 'gallery');
$aNode->nodeValue = '';
$aNode->setAttribute('href', $OurNode->getAttribute('href'));
$img = $dom->createElement('img');
$img->setAttribute("src", $OurNode->getAttribute('href'));
$img->setAttribute("alt", "");
$img->setAttribute("class", "tmp_class");
$aNode->appendChild($img);
$fragment->appendChild($aNode);
$OurNode->parentNode->replaceChild($fragment, $OurNode);
}
}
echo mb_convert_encoding($dom->saveHTML(), 'UTF-8', 'HTML-ENTITIES');
Результат
<p>С этой формы приходят заявки <a href="https://site.com/lack_tech.php">https://site.com/lack_tech.php</a><p>Или что ты имеешь ввиду?</p><div class="attachment_files_message">
<p>Прикреплённые файлы:</p>
<a data-fancybox="gallery" href="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png"><img src="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png" alt="" class="tmp_class"></a>
</div></p>
В foreach ($xpath->query('//a[@target="_blank"]') as $OurNode)
мы ищем все теги a
с атрибутом target
равным _blank
. Далее мы проверяем, заканчивается ли значение атрибута href
подстроками .jpeg
, .jpg
или .png
, затем создаем новый тег a
, добавляем к нему атрибуты, дочерний элемент img
с атрибутами, а в конце заменяем старый тег a
на новый.
Если и использовать тут регулярное выражение, стоит попробовать
preg_replace('~<a\s+((?:[^\s<>\'"=]+(?:=(?:"[^"]*"|\'[^\']*\'|[^\s\'">]+))?\s+)*)href=(?|"([^"]*\.(?:jpe?g|png))"|\'([^\']*\.(?:jpe?g|png))\'|([^\s\'">]*\.(?:jpe?g|png))(?=[>\s]))((?:\s+[^\s<>\'"=]+(?:=(?:"[^"]*"|\'[^\']*\'|[^\s\'">]+))?)*)\s*>(.*?)</a>~is',
'<a $1$3 data-fancybox="gallery" href="$2"><img src="$2" alt="" class="tmp_class"></a>',
$row["message"])
Демо регулярного выражения
Подробности
<a
- подстрока <a
\s+
- 1+ пробельных символов((?:[^\s<>'"=]+(?:=(?:"[^"]*"|'[^']*'|[^\s'">]+))?\s+)*)
- захватывающая подмаска №1: 0 и более повторов атрибутов с опциональными значениями (т.е. может быть что-то типа required
, target='_blank'
и т.д.)href=(?|"([^"]*\.(?:jpe?g|png))"|'([^']*\.(?:jpe?g|png))'|([^\s'">]*\.(?:jpe?g|png))(?=[>\s]))
- =
, за которым следуют опциональные кавычки '
/"
и захватывающая подмаска №2, которая захватывает текст внутри '...'
/ "..."
или символы, отличные от пробельных, '
, "
и >
, если значение href
заканчивается на .
+ jpeg
, jpg
или png
((?:\s+[^\s<>'"=]+(?:=(?:"[^"]*"|'[^']*'|[^\s'">]+))?)*)
- захватывающая подмаска №3: 0 и более повторов атрибутов с опциональными значениями (т.е. может быть что-то типа required
, target='_blank' и т.д.)\s*>
- 0+ пробельных символов и >
(.*?)
- захватывающая подмаска №4: 0 и более любых символов до первого вхождения</a>
- подстрока </a>
.Заменить совпадение нужно <a $1$3 data-fancybox="gallery" href="$2"><img src="$2" alt="" class="tmp_class"></a>
, так как в захватывающих группах №1 и №3 могут быть дополнительные атрибуты.
См. также PHP-демо:
$message = '<p>С этой формы приходят заявки <a href="https://site.com/lack_tech.php">https://site.com/lack_tech.php</a></p>
<p>Или что ты имеешь ввиду?</p>
<div class="attachment_files_message">
<p>Прикреплённые файлы:</p>
<a href="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png" target="_blank">Screenshot_1.png</a>
</div>';
$message = preg_replace('~<a\s+((?:[^\s<>\'"=]+(?:=(?:"[^"]*"|\'[^\']*\'|[^\s\'">]+))?\s+)*)href=(?|"([^"]*\.(?:jpe?g|png))"|\'([^\']*\.(?:jpe?g|png))\'|([^\s\'">]*\.(?:jpe?g|png))(?=[>\s]))((?:\s+[^\s<>\'"=]+(?:=(?:"[^"]*"|\'[^\']*\'|[^\s\'">]+))?)*)\s*>(.*?)</a>~is',
'<a $1$3 data-fancybox="gallery" href="$2"><img src="$2" alt="" class="tmp_class"></a>',
$message);
echo $message;
Результат
<p>С этой формы приходят заявки <a href="https://site.com/lack_tech.php">https://site.com/lack_tech.php</a></p>
<p>Или что ты имеешь ввиду?</p>
<div class="attachment_files_message">
<p>Прикреплённые файлы:</p>
<a target="_blank" data-fancybox="gallery" href="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png"><img src="http://site.com/public/uploads/kylticket/2670/Screenshot_1.png" alt="" class="tmp_class"></a>
</div>
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Всем привет, я только начинаю изучать ООП и столкнулся вот с такой проблемой
Внедряюсь/Инжектируюсь в стороннее Qt-приложениеПеребираю все QWidget, но не нахожу среди них QMainWindow
Мне нужно скопировать данные из одного std::map в другой std::map, при условии что эти данные выражены в виде указателейТо есть с помощью оператора...