2017-05-06 93 views
0

內容目前我有這個爛攤子,也沒有問如何:HTML內容的非空元素

$string = " 
<p> 
    <b>Foo1:</b> Bar1<br> 
    <b>Foo2:</b> Bar2<br> 
    <b>Foo3:</b> Bar3<br> 
    <b>Foo4:</b> Bar4 
</p> 
<br> 
<p></p> 
<br> 
<p> 
</br> 
<br /> 
<br/> 
<br> 
</p> 
" 

所以我需要修剪這一切<br>的年代和<p>的是這樣的:

$string = " 
<p> 
    <b>Foo1:</b> Bar1<br> 
    <b>Foo2:</b> Bar2<br> 
    <b>Foo3:</b> Bar3<br> 
    <b>Foo4:</b> Bar4 
</p> 
" 

我試圖做這樣的事情:

$chars = " \t\n\r\0\x0B"; 
$subpattern = '(</?(br|p) ?/?[^>]*>)'; 
$pattern = '~(^'.$subpattern.'|'.$subpattern.'$)~i'; 

trim(preg_replace($pattern, '', $string), $chars) 

但只刪除最後<p>,我怎麼能讓它正常工作?

回答

0

,而不是分析HTMLregex的,你應該使用DOMDocument,在這裏我們只是查詢DOMDocument//p/b/..

Try this code snippet here

<?php 
ini_set('display_errors', 1); 
libxml_use_internal_errors(true); 

$string = <<<HTML 
<p> 
    <b>Foo1:</b> Bar1<br> 
    <b>Foo2:</b> Bar2<br> 
    <b>Foo3:</b> Bar3<br> 
    <b>Foo4:</b> Bar4 
</p> 
</p> 
<br> 
<p></p> 
<br> 
<p> 
</br> 
<br/ > 
<br/> 
<br> 
</p> 
HTML; 
$domObject= new DOMDocument(); 
$domObject->loadHTML($string, LIBXML_HTML_NODEFDTD); 

$domXpath= new DOMXPath($domObject); 
$results=$domXpath->query('//p/b/..'); 
foreach($results as $result) 
{ 
    echo $domObject->saveHTML($result); 
} 

輸出:

<p> 
    <b>Foo1:</b> Bar1<br> 
    <b>Foo2:</b> Bar2<br> 
    <b>Foo3:</b> Bar3<br> 
    <b>Foo4:</b> Bar4 
</p> 
+0

謝謝,它完美無瑕。我怎麼也可以限制最大換行符爲5? 'if(++ $ i == 5)break;'在foreach循環中對我不起作用:s – KAYOver

0

使用strip_tags函數。 Link to function description in PHP Doc.

+0

的OP想刪除一些標籤,而不是其他的相同類型的,所以我不知道這是一個不錯的選擇。 –

+0

@LornaMitchell是的,你是對的。順便說一句,我非常喜歡你從PHPNW的演示:) – arbogastes

+0

好吧,使用'strip_tags()'*可以*工作,但是你必須將你想要允許的所有標籤列入白名單,而不是僅僅禁止標籤你不想要。可能會有更多的問題比它的幫助,正則表達式可能是要走的路。 – Qirel

0

與其嘗試正則表達式方法,不如嘗試解析HTML,然後丟棄空元素,因爲這實際上是您想要實現的。像DOMDocument :: loadHTML(http://php.net/manual/en/domdocument.loadhtml.php)這樣的東西會給你一個數組結構,你可以循環,然後一旦你刪除了你不需要的部分,就可以轉換回HTML。

0

與DOM文檔和DOMXPath的一種方法:

function isEmpty($n) { 
    $nodeList = $n[0]->childNodes; 
    foreach ($nodeList as $childNode) { 
     switch ($childNode->nodeType) { 
      case XML_ELEMENT_NODE: 
       if (!in_array($childNode->nodeName, ["p", "br"]) || 
        $childNode->nodeName == "p" && !isEmpty([$childNode])) return false; 
      case XML_TEXT_NODE: 
       if (trim($childNode->nodeValue) !== "") return false; 
     } 
    } 
    return true; 
} 

$dom = new DOMDocument; 
libxml_use_internal_errors(true); 
$dom->loadHTML($string); 
$xp = new DOMXPath($dom); 
$xp->registerNamespace("php", "http://php.net/xpath"); 
$xp->registerPHPFunctions('isEmpty'); 

$nodeList = $xp->query('//br[not(./ancestor::p)] | //p[php:function("isEmpty", .)]'); 

foreach ($nodeList as $node) { 
    $node->parentNode->removeChild($node); 
} 

foreach ($dom->getElementsByTagName('body')->item(0)->childNodes as $childNode) { 
    echo $dom->saveHTML($childNode); 
} 

demo