在一些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...