【从0做项目】Java搜索引擎(8) 停用词表 正则
阿华代码,不是逆风,就是我疯
你们的点赞收藏是我前进最大的动力!!
希望本文内容能够帮助到你!!
目录
文章导读
零:项目结果展示
一:前引
二:停用词表
1:问题引入
2:解决方式
(1)停用词表的引入
(2)停用词表的加载
3:前后结果对比
三:正则继续薄纱
1:查看源代码
2:后端代码分析
3:使用\b正则匹配
(1)简单讲解怎么用
4:后端代码修改
文章导读
阿华将发布项目复盘系列的文章,旨在:
1:手把手细致带大家从0到1做一个完整的项目,保证每2~3行代码都有详细的注解
2:通过文字+画图的方式,对项目进行整个复盘,更好的理解以及优化项目
3:总结自己的优缺点,扎实java相关技术栈,增强文档编写能力
4:目前项目已经上线,访问链接如下
Java 文档搜索
零:项目结果展示
简述:在我的搜索引擎网站,用户进行关键字搜索,就可以查询到与这个关键字相关的java在线文档,(包含标题,关键字附近的简述,url),用户点击标题,即可跳转到相关在线文档,适用于JDK17版本。
一:前引
在上一篇文章中,我们完成了相关的web模块,但是在测试,使用功能的过程中暴露出来了一些问题。本篇文章将会带领大家进行分析解决
二:停用词表
1:问题引入
我们看这一次搜索结果,我们在arraylist 间加入了空格字符,此时搜索出来的结果,右1w多条很明显是非常不合理的,才想,后端是不是把空格字符也当成我们搜索的关键词,在后端索引中进行查找匹配了。毕竟我们文档数量也没有那么多
2:解决方式
问题:把一些 a is 空格,标点。这些不应该出现在搜索词句中的字符给过滤掉
(1)停用词表的引入
停用词表类似于一个筛子,究竟哪些词需要被过滤掉呢?这就是语言学家需要考虑的问题了
这里我们在网上搜索停用词表,下载一个txt文档即可
(2)停用词表的加载
我们把这些词存到一个全局变量HashMap中去
//哈希表保存停用词
private HashSet<String> stopWords = new HashSet<>();
public void loadStopWords(){
try(BufferedReader bufferedReader = new BufferedReader(new FileReader(STOP_WORD_PATH))){
while(true){
String line = bufferedReader.readLine();//读取结果不包含\n换行
if(line == null){
break;
}
stopWords.add(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
3:前后结果对比
我们1w多个搜索结果暴减到3k多个
三:正则继续薄纱
问题引入:我们搜索完arraylist,继续往下划拉,会发现怎么还是会返回好多与搜索关键词句无关的文档?
1:查看源代码
这时候我们就要去看看这个文档的源代码了,一看确实这个package-use中存在我们的array关键词的,但是正文返回的描述中怎么会没有定位到array呢????让我看看是怎么个事?
2:后端代码分析
3:使用\b正则匹配
(1)简单讲解怎么用
这里就能识别到有右括号左边的array,666~~
这种我们在array前面也加上一个\b,那么array前面的空格也能够匹配的上,amazing。
4:后端代码修改
重新处理一下我们返回正文描述的逻辑
这里我们想用indexOf()方法来直接锁定贴近括号的那个word,但是很遗憾我们的indexOf()方法不支持正则表达式,所以我们曲线救国!!!
第一步:我们把所有word前后都给他替换成空格,形成一个个独立的单词,这样我们就能锁定word所在的位置了
不难看出右边多了个括号吧!!
不多bb直接上代码。
private String GenDesc(String content , List<Term> terms){
//遍历分词结果,看哪个
int firstPos = -1;
for(Term term : terms){
String word = term.getName();
// firstPos = content.toLowerCase().indexOf(" " + word + " ");//避免包含关系 例:查array 结果查到ArrayList
//使用正则表达式,indexOf不支持正则,我们曲线救国!!
content = content.toLowerCase().replaceAll("\\b" + word + "\\b" , " " + word + " ");//匹配标点符号和空格,全部替换成空格
firstPos = content.indexOf(" " + word + " ");//女少
if(firstPos >= 0){
break;//找到了位置,可能这个content中会包含多个term,我们只取第一个
}
}
//用户输入的词,在正文中没有出现,虽然有点扯,但还是处理一下这种情况
if(firstPos == -1){
if(content.length() > 160){
return content.substring(0,160) + "...";
}
return content;//我去测试了一下,还真有这种情况离谱!说明查的词在标题中出现了,但是正文没出现666,这里也要对正文的长度做一下判断
}
//截取一部分正文
String desc = "";
int descBeg = firstPos < 60 ? 0 : firstPos - 60;
if(descBeg + 160 > content.length()){
desc = content.substring(descBeg);
}else {
desc = content.substring(descBeg , descBeg + 160) + "...";
}
for(Term term : terms){
String word = term.getName();
desc = desc.replaceAll("(?i) " + word + " " , "<i> " + word + "</i> ");//正则忽略大小写全字段匹配,那头单词和尾单词呢?
}
return desc;
}