[轉貼] 如何去除或有條件保留 HTML 標籤

2012031217:14
收到一個需求,我們網站的產品展示頁容許產品人員編寫 HTML 語法,以達到他們想要呈現的樣子,但某些場合必須去除這些 HTML 標籤或 inline CSS,反而讓人不勝其擾…。說實話,手動一個個去除 HTML 標籤真是一件苦差事,而時常在點部落這個佛心社群的薰陶下,多少有點佛心來著也是很合理的,沒第二句話直接將需求收下!(其實是根本沒有說話的餘地…) 

第一時間覺得用 Regular Expression 來去掉 HTML 標籤應該是剛剛好而已,上網搜尋其實有很多資源,其中一篇:C# Remove HTML Tags 相當值得參考,文中作者撰寫一個 HtmlRemoval 類別,可用來完全去除 HTML 標籤,更進一步測試用 Char Array 逐字處理效能出奇的好!這邊推測是利用角括號 <、> 簡單判別會比起 Regex 模式比對要有效率。 

仍需提醒各位,利用 Char Array 逐字處理是相當快沒錯,不過你得注意 HTML 標籤一旦只有左角括號,遺漏右角括號時,將沒有任何內文被保留下來,這點其實原作者在文章內有說明,怕大家漏看了再雞婆一下,如果你實在沒有把握會不會遇到這種狀況,那建議還是採用 Regex 處理較妥當。 

事實上 Regex 還是有其優勢,那就是處理字串的能力可謂無敵啊,例如我收到的需求還要有條件保留 HTML 標籤,也就是說某些標籤可能是不希望去掉的,因此我將上述的 HtmlRemoval 類別加上底下的方法: 
/// <summary>
/// 去除 HTML 標籤,可自訂合法標籤加以保留
/// </summary>
/// <param name="src">來源字串</param>
/// <param name="reservedTagPool">合法標籤集</param>
/// <returns></returns>
public static string StripTags(string src, string[] reservedTagPool)
{
    return Regex.Replace(
        src,
        String.Format("<(?!{0}).*?>", string.Join("|", reservedTagPool)),
        String.Empty);
}

這樣一來如果我要保留圖檔以及斷行標籤可以這樣寫:
using System;

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string html = "<div><p>點部落是培養佛心的好地方!<br />" +
            "<img src=\"http://www.dotblogs.com.tw/Images/DotBlogsLogo.gif\" alt="\"Dotblogs" Logo\" /></p></div>";
        string[] reservedTagPool = { "img", "br" };

        TextBox1.Text = html;
        TextBox2.Text = HtmlRemoval.StripTags(html, reservedTagPool);
        Literal1.Text = HtmlRemoval.StripTags(html, reservedTagPool);
    }
}
 

效果參見下圖:
 

striphtml_demo
 
OK,降子佛心程式碼就大致完成囉!