Что такое регулярное выражение для удаления всех тегов 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
любые идеи одной линии или более элегантного решения, которое действительно работает?
Вы пробовали что-то вроде этого: "preg_replace (" / <h1> | <p> | </p> | </h1> / g "," ", $ string)"?
Что насчет этого? preg_replace ("/ <[^>] * [/] *> / g", "", $ string);
Regex - не лучший способ справиться с этим. Вы должны использовать DomDocument для перебора тегов и получения их значений innerHTML, добавления пробелов и т. д.
@ vivek_23 то, что вы предлагаете, излишне. Все, что я хочу сделать, это удалить весь html и вывести однострочную строку. Там, где есть теги br и p, мне нужно заменить одним пробелом, и если есть какие-либо разрывы строк, их необходимо удалить
@ adam78, это не перебор. Это решение. Regex не даст вам правильных ответов, если вы не полностью контролируете, какой HTML у вас будет.






Вы можете сгруппировать несколько тегов, окруженных пробелами, и заменить их одним пробелом. Заменяемое регулярное выражение будет таким:
(\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
Что, если в innerHTML есть < и >?
Как и хочет OP, даже этот внутренний тег будет удален. Хотя в целом html не следует манипулировать с помощью регулярных выражений, я предложил это, поскольку с этим можно справиться в случае OP. Отметьте здесь, где даже внутренние теги будут заменены пробелом с сохранением любого текста внутри тегов, если таковой имеется. Демо
Я имею в виду контент вроде x < y and a > b.
@ vivek_23: Вы когда-нибудь видели такие настоящие html-данные? Если только вы не создадите его искусственно :) Хотя я могу сделать свое регулярное выражение более жестким, если у OP есть такие данные для обработки. Вместо <[^>]+> он стал бы просто <\w[^>]*>
И если у вас есть искаженные теги, такие как < sometag some attributes etc etc>, регулярное выражение можно изменить на <\s*\w[^>]*>, чтобы обработать лишнее пространство перед именем тега. Такие небольшие изменения всегда можно легко сделать, в зависимости от данных. Но если вы не знаете, какие данные будут там, на самом деле не стоит усложнять ваше регулярное выражение.
Ну, это не обрезка. Таким образом, остается начальное и конечное пространство .... но неважно.
@ArtisticPhoenix: Я уже писал в своем посте, вы можете просто сделать trim($str), чтобы обрезать его.
@PushpeshKumarRajwanshi Я согласен, и такие HTML-данные могут быть. Возьмем, к примеру, любой математический сайт. Эти символы могут быть написаны в его DOM для объяснения некоторых математических концепций и т. д. Более того, как вы сказали ранее, регулярное выражение никогда не является решением таких проблем, и я уверен, что OP введет в заблуждение многих будущих рефереров сообщений, чтобы использовать регулярное выражение для таких вещей.
@ vivek_23: Я согласен с вами, что HTML никогда не следует анализировать с помощью регулярных выражений. Но одна из основных причин этого заключается в том, что HTML может содержать вложенные структуры, которые регулярное выражение не может обрабатывать. Но в случае OP нет вложенных тегов, и это даже не повлияло бы, если бы у него действительно были вложенные теги. Потому что все, чего хочет OP, - это избавиться от тегов. Таким образом, для этой конкретной задачи OP наверняка может написать одну строку кода для выполнения своей задачи. Таким образом, мудрость не всегда заключается в слепом следовании правилу, а в знании того, когда использовать, а когда нет. Но да, в общем случае регулярное выражение не следует использовать для HTML.
Вы можете использовать это
<\s*/?\s*br[^>]*>|<\s*/?\s*p[^>]*>|\n
Explanation
<\s*/?\s*br[^>]*> - соответствует <br>, </br> или <br/> с любым количеством пробелов и также соответствует атрибутам.<\s*/?\s*p[^>]*> - Соответствует <p>, </p> или <p/> с любым количеством пробелов, также соответствует атрибутам.\n - соответствует новой строке.Тег p может иметь атрибуты.
@Code он не заменяет верхний регистр <Br>, а также не заменяет разрывы строк и все другие теги html
@ adam78, вы можете включить для этого флаг нечувствительности к регистру. а для \n я обновил ответ
Вы можете оставить то, что у вас есть, удалить лишние пробелы
$stripped = preg_replace('/\s+/', ' ', $string);
Это возвращается:
Heading hyperlink paragraph1 paragraph2
все еще в конечном итоге и дополнительное пространство между hyperlink и paragraph1
Вот что бы я сделал:
$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
Первое регулярное выражение удаляет теги, заменяя их пробелом, второе занимает несколько пробелов и заменяет их на один.
Это работает довольно хорошо, но я вижу способ отклонения от того, что было конкретно запрошено.
What is the regex to strip all html tags and where there are <br> and <p> tags replace with a single space and remove all line breaks
Итак, если вам нужно «полное» решение, вы можете сделать это:
$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 how would I accomodate
<p> </p>
Сначала я бы преобразовал строку с помощью html_entity_decode, но с этим есть несколько проблем. Это связано с кодированием. Итак, это правильный способ сделать это:
$a = '<h1>Heading</h1>
<br>
<br />
<a href = "#">hyperlink</a>
<p> </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) This modifier turns on additional functionality of PCRE that is incompatible with Perl. Pattern and subject strings are treated as UTF-8. An invalid subject will cause the preg_* function to match nothing; an invalid pattern will trigger an error of level E_WARNING. Five and six octet UTF-8 sequences are regarded as invalid since PHP 5.3.4 (resp. PCRE 7.3 2007-08-28); formerly those have been regarded as valid UTF-8.
Проблема возникает из-за его декодирования в ASCII 160 (nbsp) вместо символа ASCII 32 (одиночный пробел). В любом случае мы можем использовать UTF-8, чтобы разобраться, как показано выше.
@ArtisticPhoenix: Вы неправильно написали мое регулярное выражение. Вам не хватает + в регулярном выражении, которое я написал. В демонстрации песочницы вы используете (\s*<[^>]+>\s*) вместо моего регулярного выражения, которое является (\s*<[^>]+>\s*)+. Я думаю, что мое регулярное выражение достаточно простое и работает за один раз.
Без шуток ... не заметил.
@ArtisticPhoenix: Все в порядке, дорогая. Но мое регулярное выражение работает и достаточно просто.
@ArtisticPhoenix: Твое тоже правильно, но разве мое не проще?
@PushpeshKumarRajwanshi - нет. У вас просто неполное регулярное выражение, в котором отсутствуют разделители. Мой - это настоящий исполняемый код, который начинающий программист может вставить прямо во что-то и начать с ним работать. Они должны выяснить несколько вещей. Если вы действительно хотите сравнить, мы можем. Но, честно говоря, мне все равно.
@ArtisticPhoenix: OP уже знает, как это сделать в кодах PHP, но тем не менее. Я также добавил в свой ответ примеры кодов php.
@ArtisticPhoenix, как мне разместить <p> </p>?
Сначала я бы использовал html_entity_decode на струне. Это лучший способ, если вы просто конвертируете его в текст, потому что он также исправит такие вещи, как амперсанд & и © или любые другие объекты html. Из-за замены рабочего места /\s+/ любое дополнительное пространство, добавленное путем преобразования неразрывного пространства, также будет сметено.
Это можно сделать с помощью двух шаблонов
P1: <[/\d\w]+.*?>
который очистит все теги.
P2: [\n\s]+ и заменить его на одиночный пробел
Пример:
$string = preg_replace( "<[/\d\w]+.*?>","",$string);
$string = preg_replace("[\n\s]+"," ",$string);
Обработка 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
@Nahiyan, я хочу удалить ВСЕ html. Вышеупомянутое было просто примером.