目录
二、介绍一种正则表达式:正向预查(positive lookahead)
一、前话
在前端实现搜索功能的时候,大家经常用到的字符串匹配方法有如下几种:
- String.indexOf(search_str)
- String.includes(search_str)
- 哈希表【利用哈希表记录搜索字符串和目标字符串中对应的单词,作匹配统计】
但是,以上这些方法,当遇到需要搜索字符串输入的字符可以 不一定要连续才能匹配、不一定要大小写匹配、字符之间可以乱序匹配 的模糊搜索时刻,那么用上述方法会增加复杂度
这里我们用强大的 正则表达式,来处理能符合上述要求的模糊搜索功能
二、介绍一种正则表达式:正向预查(positive lookahead)
(?=) 执行正则表达式中的正向预查。正向预查是一种零宽度断言,它不消耗自身字符去匹配,而是用于查看字符串中的 当前位置 之后是否能够匹配指定的模式。
*注意,这里正向预查的括号,代表里面的预查都是独立的,是接着外部正则表达式指向的位置来查的,所以当多个预查连续排列是,预查开始的位置不是上一个预查结束的位置,而是括号外部指向的、此时匹配到的位置。利用这个性质,我们可以实现模糊搜索要求的乱序字符匹配!
正则表达式中,除了正向预查外,还有其他预查方式,作出一个补充:
1、正向肯定预查 (?=pattern) 表示的是从其当前位置开始,预测后面的字符串必须匹配上pattern
2、正向否定预查 (?!pattern) 表示的是从其当前位置开始,预测后面的字符串必须匹配不上pattern
3、反向肯定预查 (?<=pattern) 表示的是从其当前位置开始,预测前面的字符串必须匹配上pattern
4、反向否定预查 (?<!pattern) 表示的是从其当前位置开始,预测前面的字符串必须匹配不上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)
}
原文地址:https://blog.csdn.net/weixin_57208584/article/details/135852333
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_62543.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!