Замените тег alt, если он не пустой

У меня есть условие регулярного выражения, которое заменяет теги 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 -->

Может кто-то помочь мне с этим. Спасибо

Безусловно, решение на основе DOM будет более ясным, но вы можете заменить )( на )[^"]*( в исходном шаблоне.

Wiktor Stribiżew 09.09.2018 14:28

Большое спасибо. Поскольку мне нужны оба условия отдельно, я использовал его во втором примере. $pattern2 ='~(<img.*? alt = ")[^"]*(.+/S.+>)~i'; Работает. Как вы думаете, это хорошо, или его можно улучшить, чтобы найти существующий тег alt и заменить его.

Key 11.09.2018 04:58

Конечно, это нужно улучшать. Используйте парсер DOM.

Wiktor Stribiżew 11.09.2018 09:00

Раньше я пробовал использовать 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. Вы также можете упомянуть более ранний комментарий регулярного выражения. Я выберу это как ответ. Спасибо

Key 11.09.2018 19:28

Пожалуйста, добавьте код DOM, который вы использовали до сих пор, к самому вопросу я проверю, что можно сделать.

Wiktor Stribiżew 11.09.2018 21:45

См. 3v4l.org/Yjm0s

Wiktor Stribiżew 11.09.2018 22:37

Я только что добавил рассматриваемый код DOM, и у меня возникли проблемы с этим. Не могли бы вы взглянуть сейчас. Спасибо

Key 11.09.2018 23:01

Вы видели $dom = new DOMDocument('1.0', 'UTF-8'); $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);?

Wiktor Stribiżew 11.09.2018 23:05

Просто попробовал, и это решило проблему с <!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;, как и вывод по умолчанию.

Key 11.09.2018 23:20

Возникла проблема с $dom = new DOMDocument('1.0', 'UTF-8'); $dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);, который возвращает одно изображение. Весь текст исчез, и если я добавлю больше изображений. Они тоже не появляются.

Key 11.09.2018 23:42

Добавьте эту строку перед кодом DOM: libxml_use_internal_errors(true);. Решает ли это все вопросы?

Wiktor Stribiżew 12.09.2018 08:38

Я добавил эту строку, но с той же проблемой ... Возвращается одно изображение. Также у этого единственного изображения нет srcset и sizes. Я пробовал запустить его здесь. Выход 3v4l.org/DvE4U пуст.

Key 12.09.2018 09:48
Ничего не удаляет.
Wiktor Stribiżew 12.09.2018 10:26

Это действительно странно. Интересно, почему Wordpress вызывает проблемы. Я тестировал все темы по умолчанию, и они возвращают только первое изображение. Пробую в файле functions.php. Проблема заключается в добавлении LIBXML в dom. Взгляните, пожалуйста, на скриншоты. Предварительный просмотр с LIBXML_HTML: prntscr.com/ktgh9t Предварительный просмотр с $ dom-> loadHTML ($ content): prntscr.com/ktgiah

Key 12.09.2018 11:10

Я могу только предложить решение проблем вручную или использовать Simple HTML DOM parser.

Wiktor Stribiżew 12.09.2018 11:17

Я пробовал с простым парсером html dom. Проблема с одним изображением решена, но код все еще модифицируется. Атрибуты srcset и sizes по-прежнему не работают. Похоже, проблема WordPress с парсингом DOM. И почему-то $image->setAttribute не работает с простым парсером html dom. Вот код. pastebin.com/d43SvejD

Key 12.09.2018 22:09

Хорошо, я вижу, что WP - это глючная штука. Итак, '~(<img\s(?:[^<]*?\s)?alt = ")[^"]*("[^<]*?>)~i' работает, не так ли?

Wiktor Stribiżew 12.09.2018 22:26

да. Этот работает и заменяет тег alt независимо от того, пуст он или нет. Но поскольку мне нужны оба условия по отдельности. Итак, я использовал это регулярное выражение, если alt не пуст. ~(<img.*? alt = ")[^"]*(.+/S.+>)~i Он работает с первым изображением, а не со всеми. Любая идея? Спасибо за помощь. Действительно ценю это.

Key 12.09.2018 22:40

Если он не пустой, вам нужен +, а не *. Попробуй '~(<img\s(?:[^<]*?\s)?alt = ")[^"]+("[^<]*?>)~i', должно быть безопаснее.

Wiktor Stribiżew 12.09.2018 22:41

Готово ... Я только что подсчитал голосование.

Key 15.09.2018 18:29
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
2
20
416
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, лучшее решение здесь

'~(<img\s(?:[^<]*?\s)?alt = ")[^"]+("[^<]*?>)~i'

Подробности

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

Другие вопросы по теме