Preg_replace поможет удалить пустой элемент «li»

Привет, мне нужен скрипт для удаления из строки html всех элементов «li», пустых или содержащих только пробелы. Но также и с внутренним пустым тегом (один или вложенные пустые теги)

Я использую этот preg_replace для успешного удаления только пустого «li». В данном случае 4-я ли.

Но я не знаю, как удалить последнюю букву «li», внутри которой есть пустой «промежуток»… есть какие-нибудь предложения? Спасибо

$contenuto = '<ol style = "margin-top: 0cm; margin-bottom: 0cm;">
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">x</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">y</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">z</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt; color: red;"> </span></li>
</ol>';

$contenuto = preg_replace('/<li[^>]*>(\s|&nbsp;)*</li>/', '', $contenuto);

echo $contenuto;

Пожалуйста, внимательно прочитайте это прекрасно написанное эссе: Вы не можете анализировать HTML с помощью регулярных выражений.

KIKO Software 06.08.2024 09:20

Возможно, эта страница может быть полезна, используя DOMDocument/xpath stackoverflow.com/questions/8603237/…

The fourth bird 06.08.2024 09:23

Или расширьте текущее регулярное выражение: <li[^>]*>(?:\s+|&nbsp;|</?span[^>]*>)*</li>

bobble bubble 06.08.2024 09:31

@bobblebubble Ты прав. К счастью, на этой странице есть и другие ответы, а здесь — другие комментарии. Суть остается неизменной: RegEx плохо анализирует HTML, который можно изменить, и этот вопрос, похоже, подразумевает, что это так. Если бы это было не так, вам бы не понадобился RegEx.

KIKO Software 06.08.2024 10:10

Перечитывая ваш вопрос, я думаю Регулярное выражение @CasimiretHippolyte очень хорошо подходит для этого, и оно построено таким удобным образом, что вы можете ориентироваться только на li-теги, добавив предварительный просмотр в начале: <(?=li\b). Я забыл, что у вас также есть &nbsp;, поэтому вам нужно добавить и его после \s* присоединения (?:&nbsp;\s*)*, в результате чего получится эта корректировка шаблона Казимира (регулярное выражение101).

bobble bubble 06.08.2024 11:21
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать 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 и хотите разрабатывать...
0
7
87
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Отвечаю на цитацию двух вещей:

  1. @bobble bubble прав, когда сказал, что можно парсить небольшие фрагменты HTML. используя Regex, особенно если вы уверены в кодировке/ язык...
  2. Вы можете использовать ChatGPT, когда имеете дело с Regex, он хорошо работает, когда вы нужно что-то простое.

Вот мой ответ:

$regex = '/<li[^>]*>(?:\s*|(?:<[^>/]+[^>]*>\s*</[^>]+>)(?:\s*|</?\w+[^>]*>\s*))</li>/s';
$contenuto = preg_replace($regex, '', $contenuto);    

Ваш RegEx не работает, когда я меняю <span> на <b>: 3v4l.org/EGb2j Вы можете возразить, что это не то, что спрашивают, но я думаю, что это так. В вопросе говорится о «тегах empy» и в качестве примера приводится <span>.

KIKO Software 06.08.2024 10:18

@KIKOSoftware действительно! Я неправильно понял вопрос, извините, обновил, теперь кажется, что он работает с любым пустым тегом.

Vincent Decaux 06.08.2024 10:43

Да, вы можете адаптировать свой RegEx, если знаете, к чему адаптироваться. Проблема с HTML в том, что он может сильно различаться. Предположим, тег <b> окружает тег <span>, тогда ваше выражение снова не работает: 3v4l.org/0Gmf3 Это может продолжаться бесконечно. Ваше выражение станет настолько сложным, что ни один здравомыслящий человек больше не сможет его понять. Попробуйте другой ответ здесь, обратите внимание, как он справляется с любым HTML и все еще в некоторой степени понятен.

KIKO Software 06.08.2024 12:30

@KIKOSoftware Я ценю возможность знать, когда что использовать, и поддерживать активное обсуждение, не осуждая одно за хорошее, а другое за плохое - все зависит от ситуации. Современные регулярные выражения могут выходить за рамки анализа обычных языков . Шаблон Казимира, о котором я упоминал выше , может работать с вложенными элементами (демо) но для того, кто не привык к регулярным выражениям, его, конечно, сложно читать и адаптировать. Для этой задачи замена регулярного выражения, вероятно, легко превзойдет анализ dom и замену. Однако я бы также использовал здесь решение Гордона (лучше использовать).

bobble bubble 06.08.2024 20:16
Ответ принят как подходящий

XPath для выбора пустых узлов li:

//li[not(normalize-space())]

Запрос XPath — это не то, что вы просили. Но я считаю, что это гораздо более кратко, читабельно и проще в использовании, чем надежное регулярное выражение, которое делает то же самое.

К сожалению, в PHP нет чего-то вроде функции xpath_replace, которая скрывает весь шаблонный код, необходимый для выполнения того, что preg_replace делает для регулярных выражений. Поэтому вам придется написать дополнительный код, чтобы получить желаемый результат:

<?php
$html = '<ol style = "margin-top: 0cm; margin-bottom: 0cm;">
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">x</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">y</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">z</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt; color: red;"> </span></li>
</ol>';

$emptyLists = '//li[not(normalize-space())]';

$dom = new DOMDocument;
$dom->loadHTML($html);
$xpath = new DOMXPath($dom);
foreach($xpath->query($emptyLists) as $node) {
    $node->parentNode->removeChild($node);
}

echo $dom->saveHTML($xpath->query('//ol')->item(0));

выведет

<ol style = "margin-top: 0cm; margin-bottom: 0cm;">
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">x</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">y</span></li>
<li style = "margin: 0cm 0cm 0cm 47.6px; text-align: justify; line-height: normal; font-size: 11pt; font-family: Calibri, sans-serif; text-indent: 0.4px;"><span style = "font-size: 10.0pt;">z</span></li>


</ol>

Демо https://3v4l.org/OA5eV

Спасибо, это отлично работает. Я изменил эту строку, чтобы добавление тега <HTML> не требовалось: $dom->loadHTML($html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

itajackass 06.08.2024 14:09

Я не думаю, что saveHTML() нужно передавать какие-либо параметры. 3v4l.org/o0K0H

mickmackusa 07.08.2024 05:43

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