[英]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.