Регулярное выражение для удаления пустых тегов <span>

Я бы хотел, чтобы такие пустые теги span (заполненные &nbsp; и пробелом) были удалены:

<span> &nbsp; &nbsp; &nbsp; </span>

Я пытался с этим регулярным выражением, но он нуждается в настройке:

(<span>(&nbsp;|\s)*</span>)

preg_replace('#<span>(&nbsp;|\s)*</span>#si','<\\1>',$encoded);

Перевод регулярного выражения Кента Фредрика на PHP:

 preg_match_all('#<span[^>]*(?:/>|>(?:\s|&nbsp;)*</span>)#im', $html, $result); 

Это будет соответствовать:

  • автозаполнение
  • охватывает многострочные линии и в любом случае
  • охватывает атрибуты
  • пролет с нерушимыми пространствами

Может быть, вы должны включать в себя только <br /> только <br />

Как обычно, когда дело доходит до настройки regexp, некоторые инструменты удобны:

http://regex.larsolavtorvik.com/

,

 qr{<span[^>]*(/>|>\s*?</span>)} 

Должен получить их суть. (Включая теги, связанные с самим стилем XML, т.е.:)

Но вы действительно не должны использовать regex для обработки HTML.

Ответ относится только к контексту вопроса, который был виден до исправления ошибок форматирования

Я полагаю, что этот диапазон генерируется некоторой программой, так как у них нет никакого атрибута.
Я недоумеваю, почему вам нужно разместить пространство, которое они заключают между угловыми скобками, но опять же я не знаю конечной цели кода.
Я думаю, что решение дается Kent: вы должны сделать матч не жадным: поскольку вы используете опцию (ы) dotall, вы будете сопоставлять все между первым пролетом и последним закрытием!

Поэтому ответ должен выглядеть так:

preg_replace('#<span>(&nbsp;|\s)*?</span>#si', '<$1>', $encoded);

(Непроверенные)

Я пытался с этим регулярным выражением, но он нуждается в настройке:

Каким образом нерегинация в исходном вопросе терпит неудачу?

Проблема возникает, когда диапазон становится вложенным: <span><span> &nbsp; </span></span> <span><span> &nbsp; </span></span>

Это пример того, почему использование регулярных выражений для анализа HTML не работает особенно хорошо. В зависимости от вашего аромата регулярного выражения эта ситуация либо невозможно обрабатывать за один проход, либо просто очень сложно. Я не знаю регулярного выражения PHP-регулятора достаточно хорошо, чтобы сказать, в какую категорию он попадает, но если единственная проблема заключается в том, что он вынимает внутренний <span> и оставляет внешний один, то вы можете просто рассмотреть, многократно повторяя вашу замену, пока не закончится все, что нужно сделать.

Если ваша единственная проблема – вложенные теги span, вы можете запустить поиск и замену с помощью регулярного выражения, которое вы имеете в цикле, пока регулярное выражение больше не найдет совпадений.

Это может быть не очень элегантное решение, но оно будет работать достаточно хорошо.

Вот мое решение проблем с вложенными тегами, все еще не полное, но близко …

 $test="<span> <span>& nbsp; </span> test <span>& nbsp; <span>& nbsp; </span> </span> & nbsp;& nbsp; </span>"; $pattern = '#<(\w+)[^>]*>(& nbsp;|\s)*</\1>#im'; while(preg_match($pattern, $test, $matches, PREG_OFFSET_CAPTURE)!= 0) {$test= preg_replace($pattern,'', $test);} 

Для коротких $ test предложений функция работает нормально. Проблема возникает при использовании длинного текста. Любая помощь будет оценена …

Изменение ответа на e-satis:

 function remove_empty_spans($html_replace) { $pattern = '/<span[^>]*(?:\/>|>(?:\s|&nbsp;)*<\/span>)/im'; return preg_replace($pattern, '', $html_replace); } 

Это сработало для меня.