如何擷取html的子字串作為內容摘要

2022-02-16 06:28:43 字數 3021 閱讀 4803

在一些web應用中,如新聞、日誌等需要在其列表中提供摘要資訊,有些cms系統中提供了摘要字段,在新聞發布時手動填寫,但更為便捷的方式是直接擷取內容的前面一段作為摘要資訊。如果內容為純字元型,不帶任何格式,那便好辦,直接取其前n個字元即可,但如果內容為html**,且不一定能保證html**一定符合規範,那便如何是好?

首先,不能直接擷取,因為你可能會失去擷取內容中已有標記的閉合標記,這樣的摘要放在列表中會造成整個頁面的html閉合失常

其次,前n個字元有可能全部是html標記,並非實際內容

再者,如果截斷位置遇到img input等自閉合標籤,需延長至其閉合的位置再截斷

總的來說,不能貿然行事,需要探查敵情,敵情就在於,普通擷取字串實際擷取位置和實際擷取長度為同乙個值,但html內容的擷取位置大於或等於擷取長度,擷取長度應只考慮純文字內容,而擷取位置應將容納了擷取長度內純文字的html標籤字元數也計算在內,於是,有了如下方案:

定義擷取長度、擷取的子字串

在擷取長度》0的情況下,迴圈遍歷html字元:

如果當前字元不處於標籤中: #純內容文字

擷取長度--

擷取的子字串 += 當前字元 #拼積擷取字串

返回擷取的子字串

如此,解決了不會在html標記中間截斷的問題,但未能解決問題1:擷取內容中的標記可能缺失閉合標記,所以上述方案需要能夠同時自動閉合擷取內容中未閉合的標籤,可能有人會問,上述方案中如何判斷當前字元是否在標籤中?呵呵,後面會介紹,先賣個關子。

**電視台準備引進《越獄》,現面向全國公布待選片名(整理版):

神奇史溝飛

文身迷綜

狐狸河的救贖

大光頭有智慧型

小史快跑

fq總動員

史溝飛和他的獄友

拯救大哥林肯

阿史正傳

八仙打洞

拿什麼來拯救我的老哥

監獄豆腐渣工程帶來的教

育意義——狐狸河監獄越獄事件全程系列跟蹤報道

監獄挖牆party

臥監藏洞

小史和他的7個男人

男人,你的名字叫屎溝飛

我的弟弟會越獄

瘋等等,? htmlagilitypack的自動閉合太不靠譜,還是自己動手吧,html的標籤閉合採取類似棧的先進後出原則,只要按序入棧再出棧,即可計算出需要補全的標記,請繼續看題:

定義擷取長度、擷取的子字串、當前字元是否在html標籤中、左閉合標籤陣列、右閉合標籤陣列

在擷取長度》0的情況下,迴圈遍歷html字元:

如果當前字元為<:

當前字元進入html標籤中

如果當前字元為》:

判斷是開始標籤還是閉合標籤,標籤名稱分別加入左、右閉合標籤中

當前字元移出html標籤中

否則:

如果當前字元在html標籤中:

當前標籤名稱 += 當前字元 #拼積當前標籤名稱

否則: #純內容文字

擷取長度--

擷取的子字串 += 當前字元 #拼積擷取字串

對左右閉合標籤陣列進行比對,左標籤陣列中多出的標籤按照逆序按照html閉合標籤格式拼接至擷取的子字串末尾

返回擷取的子字串

這個邏輯即可滿足前述3個問題,但此時仍有乙個問題,如果本身輸入html內容的各種標籤不符合規範,如何是好?這時候htmlagilitypack就有用武之地了,採用輸入html內容構造乙個htmldocument,然後再writeto輸出,會發現全部標籤已經小寫化,雖然在不合html規範的時候有這樣的標籤出現,但恐怕也是最好的解決辦法了。

文字描述中的各種判斷條件,參考下述c#**

public static string htmlsummary(string content, int length)

; //左標籤陣列、右標籤陣列

content = fixhtml(content);

foreach (var current in content)

else if (current == '>') //當前字元為》,移出html標籤

else

summary += current; //拼積擷取的子字串

}summary = summary.trim();

//從左標籤陣列中移除已閉合的標籤

tagarray.right.count);

while (tagarray.right.count > 0)

//剩餘標籤未閉合,逆序以html閉合標籤格式拼接至擷取的子字串末尾

if (tagarray.left.count > 0)

for (var i = tagarray.left.count - 1; i >= 0; i--)

return summary;

}

**********2012-02-14 14:20**********=

@elgin hou 在測試後發現第46行報錯,經確認檢查,發現是標籤入棧時的判斷有誤已更改第29行,由

else if (!tagname.trim().endswith("/") && !"img|br|input".contains(tagname.tolower()))

更正為else if (!tagname.trim().endswith("/") && !"img|br|input".split('|').contains(tagname.tolower()))

在未改正前,將把『p』、『b』等標籤也排除在外,導致左標籤陣列和右標籤陣列不匹配。

非常感謝@elgin hou,歡迎更多同仁使用和測試,共同完善。

**********2012-02-14 14:55**********=

在我自己試用的過程中發現有未能正常閉合的情況出現,除錯發現第46行,不可簡單從左標籤陣列中直接移除前右標籤陣列長度個元素,因為不一定是這前幾個元素未閉合,應嚴格按照右標籤陣列中標籤出現的順序,進行出棧操作

由tagarray.left.removerange(0, tagarray.right.count);

更改為while (tagarray.right.count > 0)

PHP擷取HTML字串

擷取html字串 static function cutstr string,length,dot pre chr 1 end chr 1 string str replace array array pre.end,pre.end,pre.end,pre.end string strcut n t...

python字串擷取子串

在python中沒有類似sub 或者substring 的方法,但是字串的擷取操作卻是更加簡單。只需要把字串看作是乙個字元陣列,擷取子串非常方便。多餘的話就不囉嗦了,看下面的例子就明白了。str 0123456789 print str 0 3 擷取第一位到第三位的字元 print str 擷取字串...

擷取包含漢字字串的子字串

擷取字串 本書字數 209.9萬字 中間的數字209.9 char test 10 測試 printf s d n test,int strlen test 得到結果是6也就是說每個漢字占用6個字元 然後測試目標字串的大小 char strlen tmp 40 本書字數 209.9萬字 printf...