Jquery + 正则表达式脚本,用于以任何顺序匹配单词以进行实时搜索



所以我刚刚遇到了一个jquery实时搜索脚本,它使用正则表达式过滤并显示与输入文本匹配并隐藏其余列表项。

问题是,它仅按升序匹配短语。

假设我的列表是:

<ul class="my_ul">
<li><a>Nvidia gtx 970 vs amd rx 390</a></li>
<li><a>Nvidia gtx 1060 vs nvidia gtx 970</a></li>
</ul>

现在,如果我输入:1060 gtx nvidia970,它应该返回第二个li,并忽略任何多余的空格。(平均值应仅以任何顺序匹配单个单词,忽略空格(

现在我正在使用这个脚本:

$("#search-input").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
// Loop through the comment list
$(".my_ul li").each(function(){
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut(200);
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}
});
// Update the count
var numberItems = count;
$("#filter-count").text("Number of Comments = "+count);
});

但这只有在单词按顺序排列时才匹配, 例如:gtx 1060 vs nvidia gtx 970

这是jsfiddle:https://jsfiddle.net/xpvt214o/257804/

请为我解决这个问题,我是初学者,刚刚遇到正则表达式,所以无法使用此处的某些代码替换正则表达式来弄清楚它是 stactoverflow。请帮忙,谢谢:)

这里要解决的问题是在filtervar 中分隔数字和字母。 事实上,正则表达式可以很方便:

filter.match(/[a-zA-Z]+|[0-9]+/g).join("|")

matches字母或数字,并将生成的数组再次joins为字符串,并用正则表达式交替作为分隔符。这使我们能够独立搜索数字和字母。

但是,有一个问题:由于数字和字母是分开的,您可能会得到意想不到的结果,例如,搜索Phantom90,将显示390和Phantom9的行。为了改进,您可以在搜索引擎中使用的引号字符串中添加"精确短语"搜索;或者使用前瞻包装分隔的元素,以筛选包含每个元素的字符串。后面的方法如下所示:

示例代码

$("#search-input").keyup(function(){
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
// Loop through the comment list
$(".my_ul li").each(function(){
var pattern = filter.trim().match(/[a-zA-Z]+|[0-9]+/g) || "";  // null coalescing: "" if null
if(pattern) {
pattern = pattern.map(function(el) { 
return '(?=.*' + el + ')';
});
//join if there is something in the array
pattern = pattern.join("");
}
//console.log(pattern.join("")); 
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(pattern, "i")) < 0) {
$(this).fadeOut(200);
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}
});
// Update the count
var numberItems = count;
$("#filter-count").text("Number of Comments = "+count);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input placeholder="Search Me" id="search-input" type="text" /> 
<ul class="my_ul">
<li><a>Nvidia gtx 970 vs amd rx 390</a></li>
<li><a>Nvidia gtx 1060 vs nvidia gtx 970</a></li>
<li><a>Phaeton vs Phantom9</a></li>
</ul>

言论:

    • 您可能不想将输入拆分为字母和数字,而是将数字而不是数字拆分为数字,即d+|D+
  • 输入过滤器中的某些特殊字符会破坏脚本,请按此处所示对其进行转义。

如果我理解您的要求,这很容易,您只需要一个全局标志,告诉您的正则表达式在第一次匹配后不要返回,而不是将逻辑Or应用于所有过滤器。

这是您问题的"正则表达式解决方案",因为我对JS的了解不够,对JS更精通的人可能会为您提供一个更加以JS为中心的解决方案。

你最终应该得到这个结果:

/(GTX|AVD|1060|970)/g

要存档:

  1. 沿空格拆分筛选器输入。
  2. 构建一个以/(开头的字符串。
  3. 连接第一个单词。
  4. |放在你的单词后面,直到你输入了所有单词。
  5. 关闭与/).
  6. g添加到在构造函数中设置的标志。

在此处查看有效的正则表达式:

const regex = /(GTX|AVD|1060|970)/g;
const str = `Bla AVD trd GTX 1060 df fggg`;
let m;
while ((m = regex.exec(str)) !== null) {
// This is necessary to avoid infinite loops with zero-width matches
if (m.index === regex.lastIndex) {
regex.lastIndex++;
}

// The result can be accessed through the `m`-variable.
m.forEach((match, groupIndex) => {
if(groupIndex == 0) {
console.log(`Found match, group ${groupIndex}: ${match}`);
}
});
}

最新更新