У меня есть условие регулярного выражения, которое заменяет теги alt изображения, если они пусты.
// <img src = "test1.jpg" alt = "">
$replacement = '$1HELLO$2';
$pattern ='~(<img.*? alt = ")("[^>]*>)~i';
$content = preg_replace($pattern, $replacement, $content);
// output <img src = "test1.jpg" alt = "HELLO">
Я пытаюсь найти способ, если тег alt не пуст, он должен заменить всю строку. Я пробовал это, но он добавит слово в начале вместо замены.
// <img src = "test2.jpg" alt = "my alternative text">
$replacement = '$1HELLO$2';
$pattern ='~(<img.*? alt = ")(.+/S.+>)~i';
$content = preg_replace($pattern, $replacement, $content);
// output <img src = "test2.jpg" alt = "HELLOmy alternative text">
Хотя я хочу, чтобы вывод был <img src = "test2.jpg" alt = "HELLO">
Обновлено: я пробовал использовать метод парсера DOM ранее, но было несколько проблем. Это код.
function replaceALT($content) {
global $post;
$post = get_post($post->ID);
$content = $post->post_content;
$alt_keyword = "HELLO";
$dom = new DOMDocument();
$dom->loadHTML($content);
$images = $dom->getElementsByTagName('img');
foreach ( $images as $image) {
if (empty($image->getAttribute("alt"))) {
$image->setAttribute('alt', $alt_keyword);
}
}
$content = $dom->saveHTML();
return $content;
}
add_filter('the_content', 'replaceALT');
Было несколько проблем. По какой-то причине он изменял содержание публикации. Тег <p> был удален и заменен на <br>. Что я решил с помощью return wpautop( $content );. Другая проблема в том, что пользовательские данные img были удалены. Например, тема WordPress TwentySeventeen возвращает подобное изображение в сообщении.
<img src = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg" alt = "" width = "3264" height = "2448" class = "alignleft size-full wp-image-24" srcset = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg 3264w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-300x225.jpg 300w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-768x576.jpg 768w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-1024x768.jpg 1024w" sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" />
Но парсер DOM возвращает вот такое изображение.
<img src = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg" alt = "HELLO" width = "3264" height = "2448" class = "alignleft size-full wp-image-24">
И поскольку мне нужно было заменить тег alt внутри div содержимого сообщения.
<!-- default output -->
<div class = "entry-content">
<p><img src = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg" alt = "" width = "3264" height = "2448" class = "alignleft size-full wp-image-24" srcset = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg 3264w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-300x225.jpg 300w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-768x576.jpg 768w, http://localhost/wp/wp-content/uploads/2018/08/image-1356510220-1024x768.jpg 1024w" sizes = "(max-width: 767px) 89vw, (max-width: 1000px) 54vw, (max-width: 1071px) 543px, 580px" />Lorem ipsum dolor sit amet</p>
</div><!-- .entry-content -->
Он возвращал такой вывод.
<!-- DOM parser output -->
<div class = "entry-content">
<p><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><br />
<html><body><img src = "http://localhost/wp/wp-content/uploads/2018/08/image-1356510220.jpg" alt = "HELLO" width = "3264" height = "2448" class = "alignleft size-full wp-image-24">Lorem ipsum dolor sit amet</body></html></p>
</div><!-- .entry-content -->
Может кто-то помочь мне с этим. Спасибо
Большое спасибо. Поскольку мне нужны оба условия отдельно, я использовал его во втором примере. $pattern2 ='~(<img.*? alt = ")[^"]*(.+/S.+>)~i'; Работает. Как вы думаете, это хорошо, или его можно улучшить, чтобы найти существующий тег alt и заменить его.
Конечно, это нужно улучшать. Используйте парсер DOM.
Раньше я пробовал использовать dom parser, но проблем было немного. Пожалуйста, проверьте код здесь: pastebin.com/UJJR84ct Так как мне нужно было заменить тег alt внутри содержимого div. Он возвращал такой вывод в середине страницы <div class = "content"><DOCTYPE><html><body>CONTENT</body></html></div>. Также по какой-то причине фильтр the_content WordPress удалял все теги <p>. Что я решил с помощью wpautop(). Можете ли вы помочь мне создать функцию парсера dom, которая выполняет поиск внутри div с помощью переменной $ content и заменяет теги alt. Вы также можете упомянуть более ранний комментарий регулярного выражения. Я выберу это как ответ. Спасибо
Пожалуйста, добавьте код DOM, который вы использовали до сих пор, к самому вопросу я проверю, что можно сделать.
См. 3v4l.org/Yjm0s
Я только что добавил рассматриваемый код DOM, и у меня возникли проблемы с этим. Не могли бы вы взглянуть сейчас. Спасибо
Вы видели $dom = new DOMDocument('1.0', 'UTF-8'); $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);?
Просто попробовал, и это решило проблему с <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"><br /><html><body>. Спасибо. Есть идеи, почему он удаляет атрибуты srcset= и sizes? Когда я использую функцию регулярного выражения. Это прекрасно работает и return $content;, как и вывод по умолчанию.
Возникла проблема с $dom = new DOMDocument('1.0', 'UTF-8'); $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);, который возвращает одно изображение. Весь текст исчез, и если я добавлю больше изображений. Они тоже не появляются.
Добавьте эту строку перед кодом DOM: libxml_use_internal_errors(true);. Решает ли это все вопросы?
Я добавил эту строку, но с той же проблемой ... Возвращается одно изображение. Также у этого единственного изображения нет srcset и sizes. Я пробовал запустить его здесь. Выход 3v4l.org/DvE4U пуст.
Это действительно странно. Интересно, почему Wordpress вызывает проблемы. Я тестировал все темы по умолчанию, и они возвращают только первое изображение. Пробую в файле functions.php. Проблема заключается в добавлении LIBXML в dom. Взгляните, пожалуйста, на скриншоты. Предварительный просмотр с LIBXML_HTML: prntscr.com/ktgh9t Предварительный просмотр с $ dom-> loadHTML ($ content): prntscr.com/ktgiah
Я могу только предложить решение проблем вручную или использовать Simple HTML DOM parser.
Я пробовал с простым парсером html dom. Проблема с одним изображением решена, но код все еще модифицируется. Атрибуты srcset и sizes по-прежнему не работают. Похоже, проблема WordPress с парсингом DOM. И почему-то $image->setAttribute не работает с простым парсером html dom. Вот код. pastebin.com/d43SvejD
Хорошо, я вижу, что WP - это глючная штука. Итак, '~(<img\s(?:[^<]*?\s)?alt = ")[^"]*("[^<]*?>)~i' работает, не так ли?
да. Этот работает и заменяет тег alt независимо от того, пуст он или нет. Но поскольку мне нужны оба условия по отдельности. Итак, я использовал это регулярное выражение, если alt не пуст. ~(<img.*? alt = ")[^"]*(.+/S.+>)~i Он работает с первым изображением, а не со всеми. Любая идея? Спасибо за помощь. Действительно ценю это.
Если он не пустой, вам нужен +, а не *. Попробуй '~(<img\s(?:[^<]*?\s)?alt = ")[^"]+("[^<]*?>)~i', должно быть безопаснее.
Готово ... Я только что подсчитал голосование.






Кажется, лучшее решение здесь
'~(<img\s(?:[^<]*?\s)?alt = ")[^"]+("[^<]*?>)~i'
Подробности
(<img\s(?:[^<]*?\s)?alt = ") - Группа 1:
<img - буквальная подстрока\s - пробел(?:[^<]*?\s)? - необязательная подстрока из 0+ символов, кроме <, как можно меньше, после которой следует пробелalt = " - буквальная подстрока[^"]+ - 1 или более символов, кроме "("[^<]*?>) - Группа 2:
" - "[^<]*? - любые символы 0+, кроме <, как можно меньше> - символ >.
Безусловно, решение на основе DOM будет более ясным, но вы можете заменить
)(на)[^"]*(в исходном шаблоне.