【JS】用正则匹配实现模糊搜索

目录

一、前话

二、介绍一种正则表达式:正向预查(positive lookahead)

三、实现模糊搜索

一、前话

在前端实现搜索功能的时候,大家经常用到的字符串匹配方法有如下几种:

  • String.indexOf(search_str)
  • String.includes(search_str)
  • 哈希表【利用哈希表记录搜索字符串和目标字符串中对应的单词,作匹配统计】

但是,以上这些方法,当遇到需要搜索字符串输入的字符可以  不一定要连续才能匹配、不一定要大小写匹配、字符之间可以乱序匹配  的模糊搜索时刻,那么用上述方法会增加复杂度

这里我们用强大的  正则表达式,来处理能符合上述要求的模糊搜索功能

二、介绍一种正则表达式:正向预查(positive lookahead)

(?=) 执行正则表达式中的正向预查。正向预查是一种零宽度断言,它不消耗自身字符去匹配,而是用于查看字符串中的 当前位置 之后是否能够匹配指定的模式

*注意,这里正向预查的括号,代表里面的预查都是独立的,是接着外部正则表达式指向的位置来查的,所以当多个预查连续排列是,预查开始的位置不是上一个预查结束的位置,而是括号外部指向的、此时匹配到的位置。利用这个性质,我们可以实现模糊搜索要求的乱序字符匹配

正则表达式中,除了正向预查外,还有其他预查方式,作出一个补充:

1、正向肯定预查 (?=pattern) 表示的是从其当前位置开始,预测后面的字符串必须匹配上pattern
2、正向否定预查 (?!pattern) 表示的是从其当前位置开始,预测后面的字符串必须匹配不上pattern
3、反向肯定预查 (?<=pattern) 表示的是从其当前位置开始,预测前面的字符串必须匹配上pattern
4、反向否定预查 (?前面的字符串必须匹配不上pattern

 

三、实现模糊搜索

其实最难的部分就是知道正向预查,并用其实现乱序匹配。另外的不一定连续匹配的要求,其实也包含在乱序匹配之中;大小写模糊,也直接可以通过regExp的匹配模式实现。

另外值得注意的是,匹配上了字符,还要控制字符数量一定是相同的。这里我们用了哈希表统计字符个数,将同一个重复的字符,我们合并在同一个正向预查中比如,我们aaa搜索字符串,如果用预查表达式(?=.*a)(?=.*a)(?=.*a),就会导致目标字符串"pang"也能匹配上,原因就是正向预查的独立性,从而对相同字符无法控制数量!!正确写法应该是(?=.*a.*a.*a)

综上,代码如下:

 //搜索用户
    const searchUser = function () {
        //支持模糊搜索
        let pattr = "^"
        let pre_look = "(?=.*"

        let word_map: any = {}
        //统计字符表,使得不仅要匹配上字符,字符数量是相同的
        nameVal.trim().split("").forEach((word) => {
            let lower = word.toLowerCase()
            if (word_map[lower]) {
                word_map[lower]++
            }
            else {
                word_map[lower] = 1
            }
        })

        //构造模式匹配字符串
        Object.keys(word_map).forEach((key) => {
            let num = word_map[key]
            pattr += pre_look
            for (let i = 0; i < num; i++) {
                if (i !== 0) pattr += ".*"
                pattr += key
            }
            pattr += ")"
        })
        pattr += ".*"

        let reg = new RegExp(pattr, 'i')
        //筛选出username字符串满足匹配格式的对象
        let filterData = tableData?.filter((item) => {
            return reg.test(item.username)
        }
        )
        console.log(filterData)
    }

你可能感兴趣的:(Web学习笔记,JavaScript学习笔记,React学习笔记,javascript,开发语言,ecmascript)