前真个隐约查询, 鉴戒于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));let Se