前端模糊搜索

本文介绍了一种基于前端的模糊查询算法优化,通过借鉴并改进grain先森的前端搜索实现,提高了搜索结果的相关性和排序效率。该算法使用正则表达式进行关键词匹配,并通过特殊标记对匹配部分进行高亮显示,同时实现了对搜索结果的智能排序,确保了关键字完全匹配的项优先显示。

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

前端的模糊查询, 借鉴于grain先森的前端搜索。在此基础上稍微的有了一点点的修改

let Searcher = (() => {
        let escapeRegExp = /[\-#$\^*()+\[\]{}|\\,.?\s]/g;
        let escapeReg = reg => reg.replace(escapeRegExp, '\\$&');
        //groupLeft 与 groupRight是对结果进一步处理所使用的分割符,可以修改
        let groupLeft = '<span style="color:red">',
            groupRight = '</span>';
        let groupReg = new RegExp(escapeReg(groupRight + groupLeft), 'g');
        let groupExtractReg = new RegExp('(' + escapeReg(groupLeft) + '[\\s\\S]+?' + escapeReg(groupRight) + ')', 'g');
        //从str中找到最大的匹配长度
        let findMax = (str, keyword) => {
            let max = 0;
            keyword = groupLeft + keyword + groupRight;
            str.replace(groupExtractReg, m => {
                //keyword完整的出现在str中,则优秀级最高,排前面
                if (keyword == m) {
                    const index = str.indexOf(keyword);    // 更希望是输入关键字,对应的应该更提前显示,权重越高
                    max = Number.MAX_SAFE_INTEGER - index;
                } else if (m.length > max) {//找最大长度
                    max = m.length;
                }
            });
            return max;
        };
        let keyReg = key => {
            let src = ['(.*?)('];
            let ks = key.split('');
            if (ks.length) {
                while (ks.length) {
                    src.push(escapeReg(ks.shift()), ')(.*?)(');
                }
                src.pop();
            }
            src.push(')(.*?)');
            src = src.join('');
            let reg = new RegExp(src, 'i');
            let replacer = [];
            let start = key.length;
            let begin = 1;
            while (start > 0) {
                start--;
                replacer.push('$', begin, groupLeft + '$', begin + 1, groupRight);
                begin += 2;
            }
            replacer.push('$', begin);

            info = {
                regexp: reg,
                replacement: replacer.join('')
            };
            return info;
        };

        return {
            search(list, keyword) {
                //生成搜索正则
                let kr = keyReg(keyword);
                let result = [];
                for (let e of list) {
                    //如果匹配
                    if (kr.regexp.test(e)) {
                        //把结果放入result数组中
                        result.push(e.replace(kr.regexp, kr.replacement)
                            .replace(groupReg, ''));
                    }
                }
                //对搜索结果进行排序
                //1. 匹配关键字大小写一致的优先级最高,比如搜索up, 结果中的[user-page,beginUpdate,update,endUpdate],update要排在最前面,因为大小写匹配
                //2. 匹配关键字长的排在前面
                result = result.sort((a, b) => {
                    return findMax(b, keyword) - findMax(a, keyword)
                });
                return result;
            }
        };
    })();

    //假设list是待搜索的列表
    let list = ['config', 'user-page', 'bind', 'render', 'beginUpdate', 'update', 'endUpdate'];
    //假设userInput是用户输入的关键字
    let userInput = 'e';

    //获取搜索的结果
    document.write(Searcher.search(list, userInput));

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值