Java8 API文档搜索引擎_3.搜索模块(实现细节)

文档搜索引擎搜索模块程序见下文:

https://blog.csdn.net/m0_63299495/article/details/157732509?spm=1011.2415.3001.5331https://blog.csdn.net/m0_63299495/article/details/157732509?spm=1011.2415.3001.5331

本文介绍搜索模块的实现细节。


目录

[1. 关于分词库Ansj的大小写转换](#1. 关于分词库Ansj的大小写转换)

[2. 关于简单匹配与独立成词匹配](#2. 关于简单匹配与独立成词匹配)

[3. 关于使用正则表达式去JS标签](#3. 关于使用正则表达式去JS标签)

[3.1 统一处理所有HTML标签](#3.1 统一处理所有HTML标签)

[3.2 使用正则表达式匹配去除script标签](#3.2 使用正则表达式匹配去除script标签)

[3.3 使用正则表达式匹配处理空格](#3.3 使用正则表达式匹配处理空格)

[3.4 在DocSearcher类验证修改后的程序](#3.4 在DocSearcher类验证修改后的程序)


1. 关于分词库Ansj的大小写转换

java 复制代码
import org.ansj.domain.Term;
import org.ansj.splitWord.analysis.ToAnalysis;

import java.util.List;

public class TestAnsj {
    public static void main(String[] args) {
        String str="The Quick Brown Fox Jumps Over The Lazy Dog";
        List<Term> terms= ToAnalysis.parse(str).getTerms();
        for(Term term: terms){
            System.out.print(" \""+term.getName()+"\",");
        }
    }
}

运行测试类:

可见分词库直接实现了大写转为小写,故而在查找时,也需要将正文统一处理为小写,才能在原文中保证命中关键词,否则可能因为大小写不同而导致查询无果,使用String提供的toLowerCase()方法即可:

java 复制代码
firstPos = content.toLowerCase().indexOf(word);

2. 关于简单匹配与独立成词匹配

java 复制代码
public class TestIndexOf {
    static  String content = "applepie pineapple apple banana";
    static String word = "apple";
    public static void main(String[] args){
        // 子串匹配
        int pos1 = content.indexOf(word);
        System.out.println("pos1: "+pos1);
        // 独立单词匹配
        int pos2 = content.indexOf(" "+word+" "); 
        System.out.println("pos2: "+pos2);
    }
}

运行测试类:

仅使用word作为参数进行定位进行的是子串匹配,可能匹配单词的一部分。

使用" "+word+" "作为参数,即是通过空格作为单词边界实现一定程度上的独立单词匹配

更严格的方式应使用正则表达式,此处使用" "可以保证绝大多数情况都定位成功,故不再复杂化。

3. 关于使用正则表达式去JS标签

3.1 统一处理所有HTML标签

在仅对HTML正文去HTML标签的情况下,在DocSearcher类实现main方法进行调用,以ArrayList作为查询词进行初步测试:

java 复制代码
    public static void main(String[] args) {
        DocSearcher docSearcher = new DocSearcher();
        Scanner scanner = new Scanner(System.in);
        while(true){
            System.out.print("请输入查询词->");
            String query = scanner.next();
            List<Result> results = docSearcher.search(query);
            for(Result result:results){
                System.out.println("----------------------------");
                System.out.println(result);
            }
        }
    }

运行结果部分截图如下:

红框内部的是JavaScript的代码,有些HTML包含script标签,在对HTML正文去标签后,JS的代码也被整理到索引中了。

3.2 使用正则表达式匹配去除script标签

可以使用正则表达式来去JS标签。正则表达式使用了一些特殊的字符串描述了一些匹配规则,Java的String中的很多方法都支持正则,如indexOf,replace,replaceAll,spilt等等。

常用如下:

(1).表示匹配一个非换行字符(即非\n,非\r);

(2)*表示匹配若干个前面的那个字符;

(3).*即表示匹配非换行字符出现若干次(包括0次);

(4).+表示匹配非换行字符出现若干次(至少1次);

故而使用<.*?>即可匹配普通标签,使用<script.*?>(.*?)</script>即可匹配script标签,其中**?表示非贪婪匹配** ,表示匹配到一个符合条件的最短结果(若不带?则表示贪婪匹配,即表示匹配到一个符合条件的最长结果

例如:<div>aaa</div><div>bbb</bbb>,若使用贪婪匹配<.*>,从第一个div始标签的<匹配到第二个div末标签的>,则包括aaa和bbb在内的整个正文都被匹配去除,这显然不是期望效果;若使用非贪婪匹配<.*?>,则表示分别匹配4个div标签,使得aaa和bbb不被匹配去除:

java 复制代码
    public String parseContentByRegex(File f){
        // 将整个文件读取到String内
        String content = readFile(f);
        // 替换script标签
        content = content.replaceAll("<script.*?>(.*?)</script>"," ");
        // 替换普通标签
        content = content.replaceAll("<.*?>"," ");
        return content;
    }

注意应先处理script标签再处理通用标签,仍以ArrayList.html为例进行测试:

java 复制代码
import java.io.File;

public class TestParseContent {
    public static void main(String[] args) {
        Parser parser=new Parser();
        File file=new File("E:/SearchEngineProject/jdk-8u441-docs-all/docs/api/java/util/ArrayList.html");
        String result = parser.parseContent(file);
        String result2 = parser.parseContentByRegex(file);
        System.out.println(result);
        System.out.println(result2);
    }
}

运行结果如下:

3.3 使用正则表达式匹配处理空格

正则表达式中**\s匹配任何空白字符,包括空格、制表符、换页符等等**,但仅使用\s+并不能表示至少一个的若干个空格,涉及到转义问题:

故而应写为:

java 复制代码
content = content.replaceAll("\\s+"," ");

再次测试parseContentByRegex:

可见多个空格已被合并处理为一个空格。

3.4 在DocSearcher类验证修改后的程序

完成修改后,在Parser类中的parseHTML方法中的parseContentBy()方法修改为parseContentByRegex()方法:再次在DocSearcher中重启main方法查看生成的标题,URL以及描述:

可见此时生成的描述已经没有了JS代码。

相关推荐
人道领域2 小时前
SSM从入门到入土(Spring Bean实例化与依赖注入全解析)
java·开发语言·spring boot·后端
long3162 小时前
Z算法(线性时间模式搜索算法)
java·数据结构·spring boot·后端·算法·排序算法
毕设源码-赖学姐2 小时前
【开题答辩全过程】以 基于Java web的宠物领养系统的设计与实现为例,包含答辩的问题和答案
java·开发语言·宠物
瑞雪兆丰年兮2 小时前
[从0开始学Java|第十三天]面向对象进阶(static&继承)
java·开发语言
小楼v2 小时前
如何实现AI生成应用部署功能
java·后端·ai·部署
望未来无悔2 小时前
系统学习算法 专题十九 优先级队列(堆)
java·算法
小虾米 ~2 小时前
JAVA引用类型
java·开发语言
星辰_mya2 小时前
Elasticsearch之中
java·服务器·数据库
fengxin_rou2 小时前
[Redis从零到精通|第三篇]:缓存更新指南
java·数据库·redis·spring·缓存