替换双换行符,但使用标记时除外

时间:2019-02-15 16:39:23

标签: php regex-negation

我有一些数据库内容作为变量,我想将双换行符转换为<p>...</p>

对于单个换行符,我想添加<br />

我可以使用:

$content = nl2br($content, false);
$content = '<p>' . preg_replace('#(<br>[\r\n\s]+){2}#', '</p><p>', $content) . '</p>';

但是,我需要排除具有h2,h3,h4,ul和ul标记内的段落。但是我仍然需要在其他HTML标签周围添加p标签,例如<strong> <blockquote> <img> <i> <em><caption>

示例文本为:

<h2>Lorem ipsum dolor sit amet, consectetur adipiscing elit</h2>

Vivamus vel tempor turpis, <strong>non rutrum quam</strong>. Suspendisse ac rhoncus felis, eget porta lectus. 

Nam vulputate sapien risus, vel vehicula mi volutpat sed. 

<ul>
<li>Sed feugiat nibh at nisl eleifend scelerisque.</li>
<li>Aliquam non maximus ipsum. Aliquam erat volutpat.</li>
</ul>

<h3>Praesent eget diam sit amet leo vehicula sagittis at quis tortor</h3>

Nunc nec sem ac nunc tincidunt aliquam ut nec dolor. Nulla facilisi.

<img alt="xxxx" src="xxx.png" class="xxxxx"/> 

<caption><i>ccccc</i></caption> 

<img alt="xxxx" src="xxx.png" class="xxxxx"/> 

<i>ccccc</i>

<strong>Nunc nec sem ac nunc tincidunt aliquam ut nec dolor. Nulla facilisi.</strong>

Vivamus vel tempor turpis, <strong>non rutrum quam</strong>. Suspendisse ac rhoncus felis, eget porta lectus.

Nunc nec
Nunc nec
Nunc nec

<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Vivamus vel tempor turpis <a href=""></a></p>&mdash; xxxxx (@xxxxxx) <a href="https://twitter.com/xxxx/status/x?ref_src=x">February 15, 2019</a></blockquote>

<script async src="" charset="utf-8"></script>

2 个答案:

答案 0 :(得分:0)

您应在如下列表中添加<< strong> br >:

$content = '<p>' . preg_replace('#([\<br\>\r\n\s]{2})#', '</p><p>', $content) . '</p>';

答案 1 :(得分:0)

我建议不要使用nl2br()函数-您将在不需要的地方各处插入<br>标签。

相反,我建议您直接在换行符处执行正则表达式,而忽略已经用标签包围的行,如下所示:

(?i)^(?!((<\/|<)(h[1-6]|ul|li|script|blockquote)(\s.+)*>))(.+)(?!(<(\/\3)>))$

如果要排除更多标签,请将它们放在(h[1-6]|ul|li|script|blockquote)组中。

我们将其分解:

  • (?i)使以下所有匹配项均不区分大小写
  • ^在行的开头断言位置
  • ?!()分组是负面的预测
  • (<\/|<)意味着我们同时匹配开始标签或结束标签
  • h[1-6]匹配h1,h2,h3等。
  • (\s.+)*>与开始标记(例如<script xyz>)中的多余垃圾
  • (.+)是我们要包装段落标签的地方
  • \3中的<(\/\3)>与我们匹配的原始标签匹配,作为结束标签

请注意,上面的正则表达式中的(.+)是第5组,这是您想使用<p>标签进行环绕的功能。您可以使用$5中的preg_replace()标签引用第一组,这样您就可以在该组中同时包裹一个开始<p>和结束$regex = '#(?i)^(?!((<\/|<)(h[1-6]|ul|li|script|blockquote)(\s.+)*>))(.+)(?!(<(\/\3)>))$#'; $content = preg_replace($regex, "<p>$5</p>", $content); 标签。

以下是实际操作的示例: https://regex101.com/r/TQGbaq/2

因此您的代码可能如下所示:

self