Java 批量刪除html中注釋內(nèi)容的方法
其實(shí)刪除html文本中的注釋有很多方法,這里就自己隨便寫了一個(gè)處理方法,權(quán)當(dāng)筆記,有需要的同學(xué)可以參考。
html文本的注釋有幾個(gè)特點(diǎn):
1. 成對出現(xiàn),有開始就一定有結(jié)束。
2. 注釋標(biāo)簽沒有嵌套,注釋開始標(biāo)簽(以下稱為 <!--)下一個(gè)一定是其對應(yīng)的結(jié)束標(biāo)簽(以下稱為 -->)。
3. 一行中可能有多個(gè)注釋標(biāo)簽對兒。
4. 注釋也可以換行。
大致有以下幾種情況:
<html>
<!--This is a head-->
<head>A Head</head>
<!--This is
a div -->
<div>A Div</div>
<!--This is
a span--><!--span in
a div--><div>a div</div>
<div><span>A span</span><div>
<!--This is a
span--><div>A div</div><!--span in a div-->
<div><span>A span</span><div>
<html>
思路:
1. 每次讀取一行文本。
2. 如果該行中只包含<!-- 與 -->,并且<!-- 在 --> 之前。直接刪除兩標(biāo)簽之間的注釋內(nèi)容,獲取其他內(nèi)容。
3. 如果該行中只包含<!-- 與 -->,但是<!-- 在 --> 之后。獲取兩個(gè)標(biāo)簽之間的內(nèi)容,并且標(biāo)注已遇到<!--標(biāo)簽。
4. 如果該行中只包含<!--,獲取標(biāo)簽前面的內(nèi)容,并且標(biāo)注已遇到<!--標(biāo)簽。
5. 如果該行中只包含-->,獲取標(biāo)簽后面的內(nèi)容,并且標(biāo)注已遇到 --> 標(biāo)簽。
6. 對該行剩下的內(nèi)容再執(zhí)行2,3,4,5步驟。
7. 保存剩下的內(nèi)容。
8. 讀取下一行。
/**
* html內(nèi)容中注釋的Detector
*
* @author boyce
* @version 2013-12-3
*/
private static class HtmlCommentDetector {
private static final String COMMENT_START = "<!--";
private static final String COMMENT_END = "-->";
// 該字符串是否是html注釋行,包含注釋的開始標(biāo)簽且結(jié)束標(biāo)簽"<!-- -->"
private static boolean isCommentLine(String line) {
return containsCommentStartTag(line) && containsCommentEndTag(line)
&& line.indexOf(COMMENT_START) < line.indexOf(COMMENT_END);
}
// 是否包含注釋的開始標(biāo)簽
private static boolean containsCommentStartTag(String line) {
return StringUtils.isNotEmpty(line) &&
line.indexOf(COMMENT_START) != -1;
}
// 是否包含注釋的結(jié)束標(biāo)簽
private static boolean containsCommentEndTag(String line) {
return StringUtils.isNotEmpty(line) &&
line.indexOf(COMMENT_END) != -1;
}
/**
* 刪除該行中的注釋部分
*/
private static String deleteCommentInLine(String line) {
while (isCommentLine(line)) {
int start = line.indexOf(COMMENT_START) + COMMENT_START.length();
int end = line.indexOf(COMMENT_END);
line = line.substring(start, end);
}
return line;
}
// 獲取開始注釋符號之前的內(nèi)容
private static String getBeforeCommentContent(String line) {
if (!containsCommentStartTag(line))
return line;
return line.substring(0, line.indexOf(COMMENT_START));
}
// 獲取結(jié)束注釋行之后的內(nèi)容
private static String getAfterCommentContent(String line) {
if (!containsCommentEndTag(line))
return line;
return line.substring(line.indexOf(COMMENT_END) + COMMENT_END.length());
}
}
/**
* 讀取html內(nèi)容,去掉注釋
*/
public static String readHtmlContentWithoutComment(BufferedReader reader) throws IOException {
StringBuilder builder = new StringBuilder();
String line = null;
// 當(dāng)前行是否在注釋中
boolean inComment = false;
while (ObjectUtils.isNotNull(line = reader.readLine())) {
// 如果包含注釋標(biāo)簽
while (HtmlCommentDetector.containsCommentStartTag(line) ||
HtmlCommentDetector.containsCommentEndTag(line)) {
// 將成對出現(xiàn)的注釋標(biāo)簽之間的內(nèi)容刪除
// <!-- comment -->
if (HtmlCommentDetector.isCommentLine(line)) {
line = HtmlCommentDetector.deleteCommentInLine(line);
}
// 如果不是注釋行,但是依然存在開始標(biāo)簽和結(jié)束標(biāo)簽,結(jié)束標(biāo)簽一定在開始標(biāo)簽之前
// xxx -->content<!--
else if (HtmlCommentDetector.containsCommentStartTag(line) && HtmlCommentDetector.containsCommentEndTag(line)) {
// 獲取結(jié)束標(biāo)簽之后,開始標(biāo)簽之前的文本,并且將 inComment設(shè)置為true
line = HtmlCommentDetector.getAfterCommentContent(line);
line = HtmlCommentDetector.getBeforeCommentContent(line);
inComment = true;
}
// 如果只存在開始標(biāo)簽,因?yàn)樽⑨寴?biāo)簽不支持嵌套,只有開始標(biāo)簽的行一定不會(huì)inComment
// content <!--
else if (!inComment && HtmlCommentDetector.containsCommentStartTag(line)) {
// 將 inComment 設(shè)置為true。獲取開始標(biāo)簽之前的內(nèi)容
inComment = true;
line = HtmlCommentDetector.getBeforeCommentContent(line);
}
// 如果只存在結(jié)束標(biāo)簽,因?yàn)樽⑨寴?biāo)簽不支持嵌套,只有結(jié)束標(biāo)簽的行一定inComment
// -->content
else if (inComment && HtmlCommentDetector.containsCommentEndTag(line)) {
// 將 inComment 設(shè)置為false。獲取結(jié)束標(biāo)簽之后的內(nèi)容
inComment = false;
line = HtmlCommentDetector.getAfterCommentContent(line);
}
// 保存該行非注釋的內(nèi)容
if (StringUtils.isNotEmpty(line))
builder.append(line);
}
// 保存該行不存在任何注釋標(biāo)簽的并且inComment = false的行
if (StringUtils.isNotEmpty(line) && !inComment)
builder.append(line);
}
return builder.toString();
}
}
當(dāng)然,還有其他很多的方法,也可以通過正則匹配刪除,也可以通過Stack標(biāo)記開始結(jié)束。
等等,以上代碼經(jīng)過測試使用,希望對有需要的同學(xué)有用。
相關(guān)文章
實(shí)例解析Java程序中正則表達(dá)式的貪婪模式匹配
貪婪模式又叫最大匹配,X?、X*、X+、X{n,}都是最大匹配,例如你要用“<.+>”去匹配“a<tr>aava </tr>abb”,也許你所期待的結(jié)果是想匹配“<tr>”,但是實(shí)際結(jié)果卻會(huì)匹配到“<tr>aava </tr>”,下面我們就來看具體看一下貪婪模式的使用.2016-05-05如何使用JFrame完成動(dòng)態(tài)模擬時(shí)鐘
本文介紹了如何使用JFrame完成動(dòng)態(tài)模擬時(shí)鐘,需要的朋友可以參考下2015-08-08java基于線程池和反射機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)完整實(shí)例
這篇文章主要介紹了java基于線程池和反射機(jī)制實(shí)現(xiàn)定時(shí)任務(wù)的方法,以完整實(shí)例形式較為詳細(xì)的分析了Java定時(shí)任務(wù)的功能原理與實(shí)現(xiàn)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-11-11Spring Boot 整合 Apache Dubbo的示例代碼
Apache Dubbo是一款高性能、輕量級的開源 Java RPC 框架,這篇文章主要介紹了Spring Boot 整合 Apache Dubbo的方法,本文通過示例說明給大家講解的非常詳細(xì),需要的朋友可以參考下2021-07-07spring boot使用RabbitMQ實(shí)現(xiàn)topic 主題
本篇文章主要介紹了spring boot使用RabbitMQ實(shí)現(xiàn)topic 主題,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-03-03java Swing實(shí)現(xiàn)選項(xiàng)卡功能(JTabbedPane)實(shí)例代碼
這篇文章主要介紹了java Swing實(shí)現(xiàn)選項(xiàng)卡功能(JTabbedPane)實(shí)例代碼的相關(guān)資料,學(xué)習(xí)java 基礎(chǔ)的朋友可以參考下這個(gè)簡單示例,需要的朋友可以參考下2016-11-11詳解Java中Array和ArrayList的比較和轉(zhuǎn)換
在 Java 編程中,arrays 和 arraylists 都是基本的數(shù)據(jù)結(jié)構(gòu),用來存放數(shù)據(jù)集合,雖然兩者的用途一樣,但是它們的特點(diǎn)極大地影響應(yīng)用的性能和靈活性,本文探討 arrays 和 arraylists 的重要特性,它們各自的強(qiáng)項(xiàng)和弱點(diǎn),,需要的朋友可以參考下2023-08-08