Удалите теги и замените все теги br и p одним пробелом - PullRequest
0 голосов
/ 28 декабря 2018

Что такое регулярное выражение для удаления всех тегов html, и где есть теги <br> и <p> заменить одним пробелом и удалить все разрывы строк?

например:

<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p></p>
<p>paragraph1</p>
<p>paragraph2</p>

Должно стать:

Heading hyperlink paragraph1 paragraph2

Я пробовал следующее:

$string = preg_replace( ["/<br\s*\/?>/i","/<\/p\s*>/i"]," ",$string);
$string = preg_replace(["/<\/?[^>]+>/", "/\r?\n|\r/"],"",$string);

Что дает мне:

Heading              hyperlink         paragraph1 paragraph2 

любые идеи одной строки или болееэлегантное решение, которое на самом деле работает?

Ответы [ 6 ]

0 голосов
/ 28 декабря 2018

Рассматривать HTML как строку и использовать регулярные выражения никогда не бывает хорошей идеей.Единственное достойное решение, в котором не используется анализатор DOM, - это использование встроенной в PHP функции strip_tags (которая использует a конечный автомат , поэтомувсе еще уязвимы для потенциальных проблем с неработающим HTML), а затем вы можете сжать полученное пространство с помощью регулярного выражения:

<?php
$html = '<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p></p>
<p>paragraph1</p>
<p>paragraph2</p>';

echo preg_replace("/\s+/", " ", strip_tags($html));

Вывод:

Heading hyperlink paragraph1 paragraph2
0 голосов
/ 28 декабря 2018

Способ сделать это - использовать два шаблона

P1 : <[\/\d\w]+.*?>, которые очистят все теги.

P2 : [\n\s]+ и замените его на один пробел

Пример:

$string = preg_replace( "<[\/\d\w]+.*?>","",$string);
$string = preg_replace("[\n\s]+"," ",$string);
0 голосов
/ 28 декабря 2018

Вот что я бы сделал:

$a = '<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p></p>
<p>paragraph1</p>
<p>paragraph2</p>';


echo trim(preg_replace(['/<[^>]*>/','/\s+/'],' ', $a));

Вывод

 Heading hyperlink paragraph1 paragraph2 

Песочница

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

Это работает довольно хорошо, но я вижу способ, которым он может отклоняться от того, что было специально запрошено.

Что такое регулярное выражение для удаления всех html-тегов и где теги
и

заменяются на один пробел и удаляются все разрывы строк

Итакесли вы хотите «полное» решение, вы можете сделать это:

$a = '<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p></p>
<p><big>p</big>aragraph1</p><p>paragraph2</p>';

echo preg_replace([
    '/<(?:br|p)[^>]*>/i', //replace br p with ' '
    '/<[^>]*>/',  //replace any tag with ''
    '/\s+/', //remove run on space
    '/^\s+|\s+$/' //trim
],[
    ' ', '', ' ', ''
], $a);

Обратите внимание, что я добавил тег <big> и удалил все пробелы между тегами <p>.Это было сделано, чтобы выделить несколько вещей.

Например, если вы берете текст из второго примера и используете его в первом, вы получите следующее (потому что большой тег):

Heading hyperlink p aragraph1 paragraph2 

Обновленный пример выводит правильно.Но, и это большое, но я изменил вводимый текст, поэтому, возможно, нет необходимости чрезмерно усложнять его.

Тэг <p> просто показывает, что он помещает пространство между ними перед удалениемвсе HTML-теги с ''.

Песочница

ОБНОВЛЕНИЕ

@ ArtisticPhoenix как мне разместить <p>&nbsp;</p>

Сначала я бы преобразовал строку, используя html_entity_decode, но с этим есть несколько неприятных моментов.Это связано с кодированием.Так что это правильный способ сделать это:

$a = '<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p>&nbsp;</p>
<p><big>p</big>aragraph1</p><p>paragraph2</p>';

 //convert entities using UTF-8
$a = html_entity_decode($a, ENT_QUOTES, 'UTF-8');

echo preg_replace([
    '/<(?:br|p)[^>]*>/i', //replace br p with ' '
    '/<[^>]*>/',  //replace any tag with ''
    '/\s+/u', //remove run on space - replace using the unicode flag
    '/^\s+|\s+$/u' //trim - replace using the unicode flag
],[
    ' ', '', ' ', ''
], $a);

Обратите внимание на добавление флага u к регулярному выражению выше /\s+/u и /^\s+|\s+$/u.

u (PCRE_UTF8) Этот модификатор включает дополнительные функции PCRE, несовместимые с Perl.Шаблонные и предметные строки рассматриваются как UTF-8.Недопустимый субъект приведет к тому, что функция preg_ * ничего не найдет;неверный шаблон вызовет ошибку уровня E_WARNING.Последовательности UTF-8 с пятью и шестью октетами считаются недействительными начиная с PHP 5.3.4 (соответственно PCRE 7.3 2007-08-28);ранее они считались действительными UTF-8.

Проблема заключается в том, что он расшифровывается в ASCII 160 (nbsp) вместо ASCII 32 символа (один пробел).В любом случае мы можем использовать UTF-8 для сортировки, как показано выше.

Песочница

0 голосов
/ 28 декабря 2018

Вы можете оставить то, что у вас есть, лишние пробелы

$stripped = preg_replace('/\s+/', ' ', $string);

Что дает: Заголовок гиперссылки пункт1 пункт2

0 голосов
/ 28 декабря 2018

Вы можете использовать это

<\s*\/?\s*br[^>]*>|<\s*\/?\s*p[^>]*>|\n

Объяснение

  • <\s*\/?\s*br[^>]*> - Совпадения <br> или </br>или <br/> с любым количеством пробелов и также соответствует атрибутам.
  • <\s*\/?\s*p[^>]*> - Совпадение <p> или </p> или <p/> с любым количеством пробелов также соответствует атрибутам.
  • \n - соответствует новой строке.

Демо

0 голосов
/ 28 декабря 2018

Вы можете сгруппировать несколько тегов, которые окружены пробелами, и заменить их одним пробелом.Заменимое регулярное выражение будет иметь вид

(\s*<[^>]+>\s*)+

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

Демо

Вот код php для демонстрации,

$html = '<h1>Heading</h1>
<br>
<br />
<a href="#">hyperlink</a>
<p></p>
<p>paragraph1</p>
<p>paragraph2</p>';

echo trim(preg_replace("/(\s*<[^>]+>\s*)+/", " ", $html));

Печать,

Heading hyperlink paragraph1 paragraph2
...