簡體   English   中英

使用PHP正則表達式將HTML元素移至其父元素上方

[英]Move a HTML element to above its parent using PHP regular expressions

我有HTML(由第三方應用程序生成),我需要以各種方式對其進行清理和修改。 我需要做的一件事情是將嵌套在包含其他文本和元素的P元素內的IMG元素移動到自己的段落中。 我知道PHP DOM擴展,並在某些方面使用了此擴展,但是對於此操作,最好使用正則表達式。 包含IMG元素的P之前可能有零個或多個P元素,IMG元素在嵌套P元素內之前或之后可能有任何元素或文本,並且單個P中可能嵌套有多個IMG元素。例如我想轉型

<p>Gah1</p><p>Blah1<img src="blah.jpg"/> Blah2</p><p>Gah2</p>

<p>Gah1</p><p><img src="blah.jpg"/></p><p>Blah1 Blah2</p><p>Gah2</p> 

我試過了:

preg_replace("/<p>(.*?)(<img\s+[^>]*\/>)(.*?)<\/p>/is", "<p>$2</p><p>$1$3</p>", $input);

但這會將IMG元素放在開始位置(因為我認為勉強的第一組仍然從字符串的開始位置開始):

<p><img src="blah.jpg"/></p><p>Gah1</p><p>Blah1 Blah2</p><p>Gah2</p>

而且每個段落只能處理一張圖片。 我還嘗試了(負)前瞻的各種組合,但也無法使它們正常工作。 救命!

因此,我不再局限於嘗試使用單個正則表達式來實現這一目標,而是最終使用了多個正則表達式和迭代:

// Check if there are any paragraphs containing images first.
if (preg_match('/<p[^>]*>.*?<img\s+[^>]*\/>.*?<\/p>/is', $input)) {
  // Get individual paragraphs.
  $paragraphs = array();
  preg_match_all('/<p[^>]*>.*?<\/p>/is', $input, $paragraphs);
  foreach ($paragraphs[0] as $para) {
    $images = array();
    if (preg_match_all('/<img\s+[^>]*\/>/is', $para, $images)) {
      // Strip images from this paragraph.
      $new_paras = preg_replace('/<img\s+[^>]*\/>/is', '', $para);

      // We put the images under the paragraph they were anchored in because they tend to 
      // be anchored in the paragraph they're visually positioned in or the one above.
      foreach ($images[0] as $img) {
        $new_paras .= "<p>$img</p>";
      }

      // Replace existing paragraph containing images.
      $input = str_replace($para, $new_paras, $input);
    }
  }
}

在嘗試使用PHP DOM擴展的過程中,發現它非常麻煩且困難,因為在修改或插入其他元素時,先前獲得的對元素的引用變得混亂(盡管我仍在使用它來清理和解析原始HTML) )。 我還發現,在正則表達式中使用負前瞻或-behind以避免匹配多個段落會導致內存不足錯誤(輸入字符串可能很長),因此在上面的代碼中首先將輸入分解為單個段落。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM