之前在网上找了好久lucene高亮的包,找了几个,但是我用的lucene是3.0以后的,而针对3.0的高亮网上是很少的,再 三决定还是自己写个高亮吧。
下面是代码:
public ArrayList<String> cutKeyWord(String keyWord, Analyzer analyzer) {// 返回分词器分割的关键字后的字符串
TokenStream tokenStream = analyzer.tokenStream("content",
new StringReader(keyWord));
tokenStream.addAttribute(TermAttribute.class);
LinkedList<String> list = new LinkedList<String>();
try {
while (tokenStream.incrementToken()) {
TermAttribute termAttribute = tokenStream
.getAttribute(TermAttribute.class);
String t = termAttribute.term();
if(!list.contains(t)){
list.add(t);
}
}
} catch (IOException e) {
System.err.println("IO异常");
}
return new ArrayList<String>(list);
}
上面这个方法主要是切割关键字,因为要高亮的话,肯定是在查询类容里高亮你所查询的关键字,而这个方法就是把关键字用分词器切割成一个个小的关键字,例如:”我是中国人“,这个关键字传入后返回的ArrayList可能就是:我,我是,中,中国人。(当然这依据于你所用的分词器了)。
@SuppressWarnings("unchecked")
public ArrayList<String> cutSite(String content,ArrayList<String> list){
ArrayList<String> l = new ArrayList<String>();
for(String s:list){
for(int i=0;i<content.length();i++){
int j = content.indexOf(s, i);
if(j<0){
break;
}
l.add(String.valueOf(j));
i=j;
}
}
Collections.sort(l,new Comparator(){
public int compare(Object a,Object b){
if(Integer.parseInt(a.toString())>Integer.parseInt(b.toString())){
Object temp = a;
a=b;
b=temp;
return 1;
}else{
return 0;
}}
});
return l;
}
上面这个方法是找到要高亮内容中所有关键字的位置(这里的位置是所有用分词器分词后关键字的位置)。方法返回的十一系列数字。例如:我要高亮显示的内容是:“我爱我的中国,中国是个很古老的国家”。这句话中出现的关键词就是:“我”,“中国”。这里是依据上面输入关键字:“我是中国人”的前提下的。
下面的方法是显示的长度,你可能搜索到的内容很长,不可能把所有的内容都显示在结果页面上,所以这里就是合理的安排显示结果长度。
public String cutString(ArrayList<String> list,String r){//这里用到的FIRST_SITE:第一次关键词在搜索内容中出现的位置的前侵多少个显示。LAST_SITE同理应该知道吧。
String text =r;
String result ="";
int listLen = list.size();
int textLen = text.length();
for(int i=0;i<list.size()-1;i++){
int site = Integer.parseInt(list.get(i));
int nextSite = Integer.parseInt(list.get(i+1));
if(i==0){
if(site>FIRST_SITE)
{
result+=text.substring(site-FIRST_SITE,site);
}else{
result+=text.substring(0,site);
}
}
if((i+1)==listLen-1){
if((nextSite+LAST_SITE)<textLen)
{
result+=text.substring(nextSite,nextSite+LAST_SITE);
}else{
result+=text.substring(nextSite,textLen);
}
}
if(nextSite-site>CENTER_SITE){
String s3 = text.substring(site,nextSite);
String center = s3.substring(0,CENTER_SITE_HALF)+"..."+s3.substring(s3.length()-CENTER_SITE_HALF, s3.length());
result+=center;
}else{
System.out.println("text="+text);
// System.out.println("site= "+site);
// System.out.println("nextSite= "+nextSite);
// System.out.println("text.length="+text.length());
System.out.println("text.site="+text.substring(site));
// System.out.println("center= "+text.substring(site,nextSite));
result+=text.substring(site,nextSite);
}
}
return result;
}
高亮的位置知道了,高亮的关键字知道了,最后就是高亮效果出来的代码了:
public String highRight(String content, ArrayList<String> list) {// 高亮显示
String text = content;
if(content!=null){
for (String term : list) {
Pattern p = Pattern.compile(term);
Matcher m = p.matcher(text);
if (m.find()) {
text = m.replaceAll(HIGH_TYPE_START + term + HIGH_TYPE_END);
}
}
}
return text;
}
有问题不懂的,可以留言。