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代码。

相关推荐
驭渊的小故事1 小时前
MyBatis XML 开发实战:从配置到 CRUD 全解析
xml·java·mybatis
哦虎!6 小时前
【JavaEE】网络初识
java
for_ever_love__6 小时前
MySQL ORDER BY 排序优化:从 Using filesort 到索引有序扫描(含双路 / 单路排序原理)
java·mysql·优化·存储·by·order·filesort
我是人✓7 小时前
Java文件上传三方式对比:从传统到SpringBoot
java·开发语言
SelectDB技术团队7 小时前
冷热分层从建到验:Storage Policy 创建、表级与分区级绑定、SHOW TABLETS 验证的完整命令
大数据·数据库·elasticsearch·搜索引擎·数据分析·apache doris·冷热分层
欣栀♡7 小时前
JVM 频繁 Full GC 先看日志括号里的 cause,jstat 的 FGC 在 JDK 8 上会骗人
java·jvm
IT研究室8 小时前
最新计算机毕业设计选题推荐-基于spring boot的葡萄酒文化宣传网站-网站-文档指导-Java-springboot
java·spring boot·课程设计
慧都小项8 小时前
MyEclipse 中创建和测试 JAX-RS REST 接口:从项目配置到 REST Explorer
java·restful·myeclipse·jax-rs
Wang's Blog8 小时前
Java 项目实战: 交友项目 - 入门案例:编写 Dubbo 服务提供者
java·dubbo·交友
秋饼8 小时前
Spring AI 2.0 结构化输出企业级实战:从 BeanOutputConverter 源码到生产级解析容错
java·ai·技术分享·后端开发