tag 与 字段的提取,使用双向链表实现

本文介绍了一种使用双向链表解析HTML的方法,旨在提取不同标签内的文本内容,并为这些文本设置不同的搜索权重,以实现更精确的搜索结果。讨论了处理不规范HTML结构的策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在上一篇中提到提取tag(包括文本),对于严格的html结构,如下:
<p>that is a p item<font>that is a font item</font></p>
希望解析的结果如下:
p:thag is a p item
font:that is a font item
...
...
就是一个tag对应夹在tag间的所有文本,这样对于搜索的意义在于,不同tag的文本其搜索意义不一样,比如<strong>that is text</strong>比<p>that is text</p>的文本显然权值大,这样在搜索时就可以设置不同的权重,以达到合理的搜索。

我的思路是这样,使用双向链表,对于出现了结束tag,就往前找开始tag,把里面的所有文本都提取出来,形成tag=>text

总体方法很简单,但是存在很多意外情况(主要是html的不规范),比如,下面的特殊tag
<img><br><br /><input><meta>很可能存在只开不闭,或者只闭不开的情况。

还有:<p>that p <font>that font p </p>that font</font>
或者:<p>that p <font> p or font</p>
这样不规范的情况,那么怎么做才合适呢?

我是这样做的,出现闭tag是,往前寻找对应的开tag,如果两个tag之间还有其他tag,就出现了不规范的情况,把两个tag,和异常tag之前的文本提取出来,删除节点,比如上面:
提取出p:that p,留下<font>p or font

具体方法:
package org.biti.html;

public class Tag {
private boolean istag;
private String tagortext;
private Tag next;
private Tag pri;

public Tag(boolean istag,String tagortext,Tag next,Tag pri){
this.istag = istag;
if(istag==true){
this.tagortext = tagortext.trim().split("\\s+")[0];
}else{
this.tagortext = tagortext.trim();
}
this.next = next;
this.pri = pri;
}
/*get set method*/
}


package org.biti.html;

public class TagList {
private Tag head = null;
private Tag tail = null;

public void rebuild(String endtag){
boolean err=false;
Tag cursor = tail;
Tag begintag = null;
while(true){
if(cursor.istag()&&cursor.gettagortext().equalsIgnoreCase(endtag)){
begintag=cursor ;break;
}
if(cursor==head) return;
cursor = cursor.getpri();
}
if(cursor == tail){
if(tail.getpri()!=null){
tail = tail.getpri();
tail.setnext(null);
return;
}
if(head==tail){
head=null;
tail=null;
return;
}
}
cursor = cursor.getnext();
StringBuffer sb = new StringBuffer();
while(true){
if(cursor.istag()){
//System.out.println("err");
err=true;
//System.out.print(endtag+":");
if(!sb.toString().isEmpty()){
System.out.println(endtag+":"+sb.toString());
}
break;
}
sb.append(cursor.gettagortext());
if(cursor==tail){
if(!sb.toString().isEmpty()){
System.out.println(endtag+":"+sb.toString());
}
if(begintag!=head){
tail = begintag.getpri();
tail.setnext(null);
}else{
head = null;
tail = null;
}
return;
}
cursor = cursor.getnext();
}
if(err){
if(begintag==head){
head = cursor;
head.setpri(null);
}else{
begintag.getpri().setnext(cursor);
cursor.setpri(begintag.getpri());
}
}

}

public void append(Tag tag){
if(tag==null){
return;
}
if(head==null){
if(tag.istag()){
head = tag;
tail = tag;
tag.setpri(null);
tag.setnext(null);
}
}else{
tail.setnext(tag);
tag.setpri(tail);
tail = tag;
tail.setnext(null);
}
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值