【问题标题】:PHP - Find opening <p> tag before a specific string and add a class to itPHP - 在特定字符串之前找到打开 <p> 标记并向其添加类
【发布时间】:2021-11-30 04:37:18
【问题描述】:

我有以下一段文字:

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
<p>Lorem Ipsum has been the industry's</p><h1>standard dummy text</h1><p>ever since the 1500s</p>
<p>When an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries</p>

我需要在字符串 standard dummy text 出现之前将一个类 (inline) 添加到开头的 &lt;p&gt; 标记。或者,如果需要/更容易,它可以在&lt;h1&gt;standard dummy text&lt;h1&gt; 中使用 h1 标记?这样我的文字就变成了:

<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
<p class="inline">Lorem Ipsum has been the industry's</p><h1 class="inline">standard dummy text</h1> <p>ever since the 1500s</p>
<p class="inline">When an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries</p>

原因是我目前必须动态地将 h1 标记放入某些文本中。这可行,但是我需要预先在段落中添加一个自定义 inline 类(它只是将显示设置为内联),以便段落和标题位于同一行。

public static function markupH1TagWithinText($h1, $text)
    {
      $pos = strpos($text, $h1);
      if ($pos !== false) {
        $replacement = '</p><h1 class="inline">' . $h1 . '</h1><p class="inline">';

        return substr_replace($text, $replacement, $pos, strlen($h1));
      }
      
      return false;
    }

【问题讨论】:

  • 你检查str_spilt函数。
  • 您不能仅通过查看 &lt;/p&gt;&lt;h1&gt;standard dummy text&lt;/h1&gt; 开始的位置来执行此操作 - 您需要从那里返回并在该方向上找到第一个先前的 &lt;p&gt;,因为那是您需要替换的标签之一。 (而且整个事情真的宁愿是 DOM 解析器的工作,而不是字符串替换或正则表达式。)
  • 我也会使用 DOM 解析器。但我不确定:为什么最后一个 &lt;p&gt; 标签会得到一个 inline CSS 类?添加&lt;h1&gt; 标签是工作的一部分吗?它已经存在于输入文本中。
  • 是否需要在受影响的&lt;h1&gt; 之后的每个&lt;p&gt; 中添加inline 类?还是只是第一个?
  • @EnricoDias 只是之后的第一个

标签: php string str-replace strpos


【解决方案1】:

您可能需要一个 DOM 解析器。 PHP 有默认启用的原生 DOM extension

遍历所有&lt;p&gt; 元素并在元素内容中搜索您的字符串。如果找到它,将元素拆分为 2 并在其间插入新的 &lt;h1&gt;。您可以轻松地将自定义类添加到您需要的任何元素中。

这是一个工作示例:

$html = <<< HTML
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
<p>Lorem Ipsum has been the industry's standard dummy text ever since the 1500s</p>
<p>When an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries</p>
HTML;

$text = 'standard dummy text';

$dom = new DOMDocument();
$dom->loadHTML($html);

$pNodes = $dom->getElementsByTagName('p');
foreach($pNodes as $node) {
    if (\stripos($node->nodeValue, $text) !== false) {
        list($valueBefore, $valueAfter) = \explode($text, $node->nodeValue, 2);

        $node->nodeValue = $valueBefore;
        $node->setAttribute('class', 'inline');

        $h1 = $dom->createElement('h1', $text);
        $h1->setAttribute('class', 'inline');
        $node->append($h1);

        $pAfter = $dom->createElement('p', $valueAfter);
        $pAfter->setAttribute('class', 'inline');
        $node->append($valueAfter);
        
        $node->nextElementSibling->setAttribute('class', 'inline');
    }
}

echo $dom->saveHTML();

输出:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd">
<html><body>
<p>Lorem Ipsum is simply dummy text of the printing and typesetting industry.</p>
<p class="inline">Lorem Ipsum has been the industry's <h1 class="inline">standard dummy text</h1> ever since the 1500s</p>
<p class="inline">When an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries</p>
</body></html>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多