2014-09-12 76 views
1

我正在顯示已寫入wysiwyg編輯器(未使用外部css)的內容(名爲$ ps的字符串填充爲html),幷包含空白空間,如php刪除不包圍內容的html標記

<p> 

<span style="font-family: Calibri, sans-serif; font-size: 11pt;"> 
    <br></br> 
</span> 
<span style="font-size: 11pt; font-family: Calibri, sans-serif;"> 
</span> 

</p> 

我想刪除使用PHP(因爲我希望作者繼續不小心添加空的東西)。

到目前爲止,我有這非常低效代碼:

$ps = preg_replace('#class="(.*?)"#', '',$ps); 
$ps = preg_replace('#style="(.*?)"#', '',$ps); 
$ps = preg_replace('#<br\s*/*>#i', '',$ps); 
$ps = preg_replace('#<span\s*/*>#i', '',$ps); 
$ps = preg_replace('#<p>\s*</p>#i', '',$ps); 

大約是一半好,讓我:

<p> 

</p> 
<p> 

</p> 

,我懷疑,如果它不會可靠地工作空的東西看起來有點不同。

你能幫我建立一個更好的解決方案,我可以輕鬆實現嗎?也許一個正則表達式的工作,不像我到目前爲止的嘗試..

謝謝!

+1

第一件事情首先(不管這是否是一個好的方法來做到這一點)preg_replace可以採取一個正則表達式的數組。即:'preg_replace(array#'#class =「(。*?)」#','#style =「(。*?)」#','# #i','# #i',' #

\ s *

#i'),'',$ ps);' – 2014-09-12 16:07:08

+2

我想你應該使用[DOMXPath](http://docs.php.net/DOMXPath)刪除空的節點。正則表達式對HTML不好。檢查這2個SO解決方案。 http://stackoverflow.com/questions/8603237/remove-empty-tags-from-a-xml-with-php和http://stackoverflow.com/questions/11744454/xpath-to-recursively-remove-empty- dom-node – bansi 2014-09-12 16:12:49

+0

用正則表達式解析HTML是悲傷的祕訣。當您的用戶輸入與您的期望不符時,您的正則表達式將會中斷。例如,如果您的''

'標籤位於不同的行上?用正則表達式修改HTML更糟糕。使用合適的HTML解析器。 – 2014-09-12 16:19:59

回答

1

我會使用DOM文檔,而不是正則表達式:

$html = '<span style="font-family: Calibri, sans-serif; font-size: 11pt;">...'; 

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

$domx = new DOMXPath($domd); 
$items = $domx->query("//*"); 

foreach($items as $item) { 
    $item->removeAttribute("style"); 
    $item->removeAttribute("class"); 
} 

echo $domd->saveHTML(); 

您也可以刪除空節點,或其他任何你需要刪除。

+0

類似'if(trim($ item-> nodeValue) =='')$ item-> parentNode-> removeChild($ item);'可以做到這一點,雖然我沒有測試 – 2014-09-12 16:18:36

+0

@ wolffer-east這應該工作。 – ovi 2014-09-12 16:23:10

+0

感謝所有人!該解決方案已基本完成。如果(trim($ item-> nodeValue)=='')$ item-> parentNode-> removeChild($ item);現在我在$ html和Umlaute中遇到了問題。 只刪除第一個/某些出現的空節點。我還沒有弄清楚這取決於什麼。 – user148585 2014-09-12 16:39:05

0

在回答評論來自@ Ovi全的回答,因爲在註釋代碼塊醜陋

你可以運行它,直到它不再從集合中移除元素的東西。如果它是一個很長的文件,這將拖延,但我想它會起作用。

例如

$changed = true; 
while ($changed = true){ 
    $changed = false; 
    foreach($items as $item) { 
    if (trim($item->nodeValue) == ''){ 
     $item->parentNode->removeChild($item); 
     $changed = true; 
    } 
    } 
} 

我重申,這可能需要一個comparitively很長一段時間。另外,我還沒有測試過$item->parentNode->removeChild($item);

+0

謝謝,我明白你的意思了。不幸的是,removeChild最終試圖刪除非對象?即使這個循環是查詢後唯一的事情.. – user148585 2014-09-12 17:27:03

+0

不幸的是,我並不是操縱domdocument的專家。你可以給'(trim($ item-> nodeValue)==''&& $ child-> nodeName!=「#text」)'試一試。 – 2014-09-12 17:40:10

+0

不幸的是沒有做到這一點。儘管如此,非常感謝你的幫助! – user148585 2014-09-12 17:59:25