Java 批量删除html中注释内容的方法
其实删除html文本中的注释有很多方法,这里就自己随便写了一个处理方法,权当笔记,有需要的同学可以参考。
html文本的注释有几个特点:
1. 成对出现,有开始就一定有结束。
2. 注释标签没有嵌套,注释开始标签(以下称为 <!--)下一个一定是其对应的结束标签(以下称为 -->)。
3. 一行中可能有多个注释标签对儿。
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. 如果该行中只包含<!-- 与 -->,并且<!-- 在 --> 之前。直接删除两标签之间的注释内容,获取其他内容。
3. 如果该行中只包含<!-- 与 -->,但是<!-- 在 --> 之后。获取两个标签之间的内容,并且标注已遇到<!--标签。
4. 如果该行中只包含<!--,获取标签前面的内容,并且标注已遇到<!--标签。
5. 如果该行中只包含-->,获取标签后面的内容,并且标注已遇到 --> 标签。
6. 对该行剩下的内容再执行2,3,4,5步骤。
7. 保存剩下的内容。
8. 读取下一行。
/**
* html内容中注释的detector
*
* @author boyce
* @version 2013-12-3
*/
private static class htmlcommentdetector {
private static final string comment_start = "<!--";
private static final string comment_end = "-->";
// 该字符串是否是html注释行,包含注释的开始标签且结束标签"<!-- -->"
private static boolean iscommentline(string line) {
return containscommentstarttag(line) && containscommentendtag(line)
&& line.indexof(comment_start) < line.indexof(comment_end);
}
// 是否包含注释的开始标签
private static boolean containscommentstarttag(string line) {
return stringutils.isnotempty(line) &&
line.indexof(comment_start) != -1;
}
// 是否包含注释的结束标签
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;
}
// 获取开始注释符号之前的内容
private static string getbeforecommentcontent(string line) {
if (!containscommentstarttag(line))
return line;
return line.substring(0, line.indexof(comment_start));
}
// 获取结束注释行之后的内容
private static string getaftercommentcontent(string line) {
if (!containscommentendtag(line))
return line;
return line.substring(line.indexof(comment_end) + comment_end.length());
}
}
/**
* 读取html内容,去掉注释
*/
public static string readhtmlcontentwithoutcomment(bufferedreader reader) throws ioexception {
stringbuilder builder = new stringbuilder();
string line = null;
// 当前行是否在注释中
boolean incomment = false;
while (objectutils.isnotnull(line = reader.readline())) {
// 如果包含注释标签
while (htmlcommentdetector.containscommentstarttag(line) ||
htmlcommentdetector.containscommentendtag(line)) {
// 将成对出现的注释标签之间的内容删除
// <!-- comment -->
if (htmlcommentdetector.iscommentline(line)) {
line = htmlcommentdetector.deletecommentinline(line);
}
// 如果不是注释行,但是依然存在开始标签和结束标签,结束标签一定在开始标签之前
// xxx -->content<!--
else if (htmlcommentdetector.containscommentstarttag(line) && htmlcommentdetector.containscommentendtag(line)) {
// 获取结束标签之后,开始标签之前的文本,并且将 incomment设置为true
line = htmlcommentdetector.getaftercommentcontent(line);
line = htmlcommentdetector.getbeforecommentcontent(line);
incomment = true;
}
// 如果只存在开始标签,因为注释标签不支持嵌套,只有开始标签的行一定不会incomment
// content <!--
else if (!incomment && htmlcommentdetector.containscommentstarttag(line)) {
// 将 incomment 设置为true。获取开始标签之前的内容
incomment = true;
line = htmlcommentdetector.getbeforecommentcontent(line);
}
// 如果只存在结束标签,因为注释标签不支持嵌套,只有结束标签的行一定incomment
// -->content
else if (incomment && htmlcommentdetector.containscommentendtag(line)) {
// 将 incomment 设置为false。获取结束标签之后的内容
incomment = false;
line = htmlcommentdetector.getaftercommentcontent(line);
}
// 保存该行非注释的内容
if (stringutils.isnotempty(line))
builder.append(line);
}
// 保存该行不存在任何注释标签的并且incomment = false的行
if (stringutils.isnotempty(line) && !incomment)
builder.append(line);
}
return builder.tostring();
}
}
当然,还有其他很多的方法,也可以通过正则匹配删除,也可以通过stack标记开始结束。
等等,以上代码经过测试使用,希望对有需要的同学有用。
上一篇: 案例--简易ATM