2017-12-27 184 views
-3

我想刪除像破碎的HTML標籤:正則表達式破HTML匹配

<p>right here</p>....<iframe class 
<b>Very nice</b>...<ifr 

等我的把內容限制在HTML字符串腳本的休息和關閉是工作的罰款任何打開的標籤,這破壞的標籤將始終在字符串的結尾處。 到目前爲止,我實現的是:

#<[^>]*#i 

的問題是,它認爲部分標籤 <iframe爲好。

IFRAME只是舉例...

編輯: 我的PHP版本不支持DOM文檔,這就是爲什麼要對正則表達式。我已經實現了Closing open HTML tags用於關閉字符串中的任何打開標籤,但它允許打破標籤。

+0

可能的重複[使用PHP關閉或修復損壞的img標記](https://stackoverflow.com/questions/25846098/close-or-fix-a-broken-img-tag-using -php) – iainn

+0

但是我不想使用DOMDocument –

+2

爲什麼不呢?這是標準的PHP擴展,用於處理可能損壞的標記。 – iainn

回答

0

使用標準的PHP擴展總是最好的選擇。但是,對於那些誰是同樣的問題,並通過PHP版本的限制,這是一個完美的把長度限制在任何HTML字符串的函數:在我的情況完全工作

/** 
* Crops HTML text ensuring valid HTML 
* 
* @param string HTML string 
* @param int  The length up to which HTML string is to be limited 
*/ 
protected function limitHtml($html, $length) 
{ 
    // Ignoring style tags for displayable string length 
    preg_match_all('/<style>(.*?)<\/style>/s', $html, $cssMatches); 
    $html = preg_replace('/<style>(.*?)<\/style>/s', '', $html); 
    // css 
    $css = ''; 
    if (isset($cssMatches[1])) { 
    foreach ($cssMatches[1] as $cmatch) { 
     $css .= "<style>$cmatch</style>"; 
    } 
    }  
    $truncatedText = substr($html, 0, $length); 
    $pos = strpos($truncatedText, ">"); 
    if($pos !== false) 
    { 
     $html = substr($html, 0,$length + $pos + 1); 
    } 
    else 
    { 
     $html = substr($html, 0,$length); 
    } 

    // Relace The Broken Opened Tag From The the end of String 
    $lastCorruptopnArrow = strrpos($html, "<"); 
    $lastCloseArrow = strrpos($html, ">"); 
    if ($lastCloseArrow < $lastCorruptopnArrow) { 
    $corruptHTmlString = substr($html, $lastCorruptopnArrow, strlen($html) - $lastCorruptopnArrow); 
    $html = preg_replace('/'. preg_quote($corruptHTmlString, '/') . '$/', '', $html); 
    } 

    preg_match_all('#<(?!meta|img|br|hr|input\b)\b([a-z]+)(?: .*)?(?<![/|/ ])>#iU', $html, $result); 

    $openedtags = $result[1]; 
    preg_match_all('#</([a-z]+)>#iU', $html, $result); 
    $closedtags = $result[1]; 
    $len_opened = count($openedtags); 
    if (count($closedtags) == $len_opened) 
    { 
     return $css . $html; 
    } 
    $openedtags = array_reverse($openedtags); 
    for ($i=0; $i < $len_opened; $i++) 
    { 
     if (!in_array($openedtags[$i], $closedtags)) 
     { 
      $html .= '</'.$openedtags[$i].'>'; 
     } 
     else 
     { 
      unset($closedtags[array_search($openedtags[$i], $closedtags)]); 
     } 
    } 
    return $css . $html; 
} 

。打開以增強:limit_html()

1

您需要使用任何HTML解析器來獲得正確的結果,但這是正則表達式的方法,您希望

(<\w+(?:\s+\w+=\"[^"]+\")*)(?=[^>]+(?:<|$)) 

demo and some explanation

使用

$res = preg_replace('/(<\w+(?:\s+\w+=\"[^"]+\")*)(?=[^>]+(?:<|$))/, '$1>', $str);