【问题标题】:Adding a class to each paragraph tag using PHP Regex [closed]使用 PHP Regex 为每个段落标签添加一个类 [关闭]
【发布时间】:2015-05-23 06:58:05
【问题描述】:

$content 变量包含一个带有 HTML 段落标签的字符串,例如:

$content = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
<p>Aliquam mauris diam, gravida eget finibus varius.</p>";

如何使用 PHP 正则表达式将“textStyle”类添加到 每个 段落,使其看起来像这样:

$content = "<p class="textStyle">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <p class="textStyle">Aliquam mauris diam, gravida eget finibus varius.</p>";

这是我迄今为止尝试过的:

<?php

$content = "<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <p>Aliquam mauris diam, gravida eget finibus varius.</p>";

    $pattern = "/(<p)/";

    $replace = '<p class="textStyle"';

    preg_replace($pattern, $replace, $content);

?>

【问题讨论】:

标签: php regex


【解决方案1】:

正则表达式(不建议):

如果您必须使用正则表达式,您可以尝试这样的方法。它与 DOM 操作的能力不匹配(请参阅下面我的答案的其余部分),但如果您确定您的 &lt;p&gt; 标记在没有任何现有类的情况下是一致的,那么您可以试试这个:

$pattern = "/<p([> ])/";
$replace = '<p class="textStyle"$1';
$content = preg_replace($pattern, $replace, $content);

这将仅匹配 &lt;p&gt;&lt;p 以便尝试保留您可能拥有的任何其他属性。但是,使用正则表达式很难正确处理更复杂的情况,例如 &lt;p id="row1" class="class1"&gt;q&gt;&lt;p(一些表情符号)。


DOM 操作:

要获得更好的解决方案(不使用正则表达式),您可以改为执行以下操作。之所以如此优越,是因为您还可以替换类属性,并自动维护其他属性。另外,如果存在 HTML 验证错误,DOMDocument 对象会记录这些错误。

<?php

$content = "<p class=\"oldClass\">Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>
    <p style=\"color:red\">Aliquam mauris diam, gravida eget finibus varius.</p>";

$dom = new DOMDocument();
$dom->loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

// Evaluate P tags in HTML. This just shows
// that you can be more selective on your tags
$xpath = new DOMXPath($dom);
$tags = $xpath->evaluate("//p");

// Loop through all the found tags
foreach ($tags as $tag) {

    // Set class attribute        
    $tag->setAttribute("class", "textStyle");
}

// Save the HTML changes
$content = $dom->saveHTML();

结果:

<p class="textStyle">Lorem ipsum dolor sit amet, consectetur adipiscing elit.
<p style="color:red" class="textStyle">Aliquam mauris diam, gravida eget finibus varius.</p></p>

特别注意这一点:

loadHTML($content, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);

没有这个,你将结束 HTML 包装标签。

【讨论】:

  • 永远不要尝试使用正则表达式解析 XML/HTML。
  • OP 用给定的字符串询问了一个特定的问题。他没有说是不是整页。总的来说,我同意你的看法,但对于一个小字符串(如我所说),他可能会没事。
  • 仅供参考:如果 p 标签已经具有类属性或标签名称后跟换行符,则此正则表达式将无法正常工作。
  • 我现在改变了我的投票。 (我仍然认为你应该完全删除任何正则表达式“解决方案”)但有一件事 - getElementsByTagName 上的 foreach 不会在这里更简单吗?
【解决方案2】:

以下是使用 DOM 的方法:

<?php

$DOM = new DOMDocument();
$DOM->loadHTML("<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p>\n<p>Aliquam mauris diam, gravida eget finibus varius.</p>");

$list = $DOM->getElementsByTagName('p');

foreach($list as $p){
    $p->setAttribute('class', 'textStyle');
  }

$DOM=$DOM->saveHTML();
echo $DOM;

demo

【讨论】:

  • 我了解您更喜欢正则表达式解决方案。作为 regex 的忠实粉丝,我应该注意到更改 XML 或 HTML 结构将迫使您切换到 DOM。我认为迟早。
【解决方案3】:

它有效,但你必须这样做:

$content = preg_replace($pattern, $replace, $content);

【讨论】:

  • OP 的正则表达式将匹配任何以“p”字符开头的标签,并且即使标签已经有一个,也会添加类。
  • 不幸的是,这是公认的答案。
【解决方案4】:

试试这个:

$pattern = "/<p/";
$replace = '<p class="textStyle"';
preg_replace($pattern, $replace, $content);

【讨论】:

  • g 在 preg_replace() 中是隐含的,你不需要包含它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-13
  • 2012-01-19
  • 1970-01-01
  • 2021-09-24
相关资源
最近更新 更多