【问题标题】:Strip tags and replace all br and p tags with a single space剥离标签并用单个空格替换所有 br 和 p 标签
【发布时间】:2018-12-28 16:55:08
【问题描述】:

去除所有 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 

任何关于单行或更优雅的解决方案的想法实际上有效?

【问题讨论】:

  • @Nahiyan 我想删除所有 html。以上只是一个例子。
  • 您是否尝试过这样的操作:“preg_replace("/

    |

    |

    |/g", " ", $string)"?
  • 这个怎么样? preg_replace("/]*[/]*>/g", " ", $string);
  • 正则表达式不是处理这个问题的好方法。您应该使用 DomDocument 来遍历标签并获取它们的 innerHTML 值并添加空格等。
  • @adam78 这不是矫枉过正。这是解决方案。除非您完全控制要拥有的 HTML 类型,否则正则表达式不会给您正确的答案。

标签: php regex preg-replace


【解决方案1】:

这就是我会做的:

$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 

Sandbox

第一个正则表达式删除标签用空格替换它们,第二个正则表达式需要多个空格并将其更改为一个。

这工作得很好,但我可以看到它可能会偏离具体要求的方式。

什么是去除所有 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);

请注意,我在其中添加了一个&lt;big&gt; 标签并删除了&lt;p&gt; 标签之间的任何空格。这样做是为了强调一些事情。

例如,如果您从第二个示例中获取文本并在第一个示例中使用它,您将得到这个(因为大标签):

Heading hyperlink p aragraph1 paragraph2 

更新后的示例输出正确。但是,这是一个很大的但是,我改变了输入文本,所以可能没有必要过度复杂。

&lt;p&gt; 标记只是表明它在删除所有带有 '' 的 HTML 标记之前在它们之间放置了空格。

Sandbox

更新

@ArtisticPhoenix 我将如何容纳&lt;p&gt;&amp;nbsp;&lt;/p&gt;

首先,我将使用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);

请注意在/\s+/u/^\s+|\s+$/u 上方的正则表达式中添加了u 标志。

u (PCRE_UTF8) 此修饰符打开与 Perl 不兼容的 PCRE 的附加功能。模式和主题字符串被视为 UTF-8。无效的主题将导致 preg_* 函数不匹配;无效的模式将触发 E_WARNING 级别的错误。自 PHP 5.3.4 (resp. PCRE 7.3 2007-08-28) 起,五个和六个八位字节的 UTF-8 序列被视为无效;以前那些被认为是有效的 UTF-8。

问题在于将其解码为 ASCII 160 (nbsp) 而不是 ASCII 32 字符(单个空格)。无论如何我们可以使用 UTF-8 进行排序,如上所示。

Sandbox

【讨论】:

  • @ArtisticPhoenix:你写错了我的正则表达式。你在我写的正则表达式中缺少+。在您的沙盒演示中,您使用的是 (\s*&lt;[^&gt;]+&gt;\s*) 而不是我的正则表达式 (\s*&lt;[^&gt;]+&gt;\s*)+ 我认为我的正则表达式很简单,并且可以一次性使用。
  • 不开玩笑...没注意到。
  • @ArtisticPhoenix:没关系,亲爱的。但我的正则表达式有效,而且很简单。
  • @ArtisticPhoenix:你的也是正确的,但我的不是更简单吗?
  • @PushpeshKumarRajwanshi - 没有。你的只是一个不完整的正则表达式,缺少分隔符。我的是实际的可运行代码,新手程序员可以直接插入某些东西并开始获得经验。你的他们必须弄清楚一些事情。如果你真的想比较,我们可以。但坦率地说,我并不在乎。
【解决方案2】:

将 HTML 视为字符串并使用正则表达式绝不是一个好主意。唯一不涉及 DOM 解析器的不错的解决方案是使用 PHP 的内置 strip_tags 函数(usesstate machine,因此仍然容易受到 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

【讨论】:

    【解决方案3】:

    做到这一点的方法是使用两种模式

    P1&lt;[\/\d\w]+.*?&gt; 这将清除所有标签。

    P2 : [\n\s]+ 并将其替换为 single Whitespace

    示例:

    $string = preg_replace( "<[\/\d\w]+.*?>","",$string);
    $string = preg_replace("[\n\s]+"," ",$string);
    

    【讨论】:

      【解决方案4】:

      你可以用这个

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

      解释

      • &lt;\s*\/?\s*br[^&gt;]*&gt; - 匹配 &lt;br&gt;&lt;/br&gt;&lt;br/&gt; 与任意数量的空格并匹配属性。
      • &lt;\s*\/?\s*p[^&gt;]*&gt; - 匹配 &lt;p&gt;&lt;/p&gt;&lt;p/&gt; 与任意数量的空格匹配属性也。
      • \n - 匹配新行。

      Demo

      【讨论】:

      • p 标签可以有属性。
      • @Code 它不会替换大写 &lt;Br&gt; 也不会替换换行符和所有其他 html 标记
      • @adam78 您可以为此打开不区分大小写的标志。对于\n,我已经更新了答案
      【解决方案5】:

      您可以将多个被空格包围的标签分组,并用一个空格替换它们。要替换的正则表达式是,

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

      这将为您提供一个空格来代替所有这些标签,最后使用trim() 去除您可能不需要的最右边和最左边的空格。

      Demo

      这里是演示的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 有&lt;&gt; 怎么办?
      • 就像 OP 想要的那样,即使是那些内部标签也会被删除。尽管通常不应使用正则表达式来操作 html,但我建议这样做,因为可以处理 OP 的情况。在这里检查,即使内部标签也将被替换为保留标签内的任何文本(如果有)的空间。 Demo
      • 我的意思是像 x &lt; y and a &gt; b 这样的内容。
      • @vivek_23:你见过这样的真实html数据吗?除非你人为地做一个:) 虽然如果 OP 有这样的数据要处理,我可以让我的正则表达式更严格。而不是&lt;[^&gt;]+&gt;,它会变成&lt;\w[^&gt;]*&gt;
      • 如果你有像&lt; sometag some attributes etc etc&gt;这样的格式错误的标签,正则表达式可以更改为&lt;\s*\w[^&gt;]*&gt;以处理标签名称前的额外空间。这种小的修改总是可以很容易地完成,具体取决于数据。但是,除非您知道将存在什么样的数据,否则将正则表达式复杂化是不值得的。
      【解决方案6】:

      您可以保留现有的内容并删除多余的空格

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

      返回:

      Heading hyperlink paragraph1 paragraph2
      

      【讨论】:

      • hyperlinkparagraph1之间仍然有额外的空间
      猜你喜欢
      • 2016-10-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-02
      • 1970-01-01
      • 2020-10-31
      • 2020-12-09
      • 2015-08-15
      相关资源
      最近更新 更多