我有一些元素:
<p>Windows Phone 7</p>
<p>Windows Phone 7.5 "Mango"</p>
<p>Phone Windows 7</p>
- 如果我搜索
Phone 7
,它应该返回所有结果。 - 如果我搜索
7 Windows
,它应该返回所有结果。 - 如果我搜索
"Phone Windows"
,它应该只返回最后一个元素。
基本上用户将在input
中输入一些文本,我想用Regex实现AND
和OR
。
我如何实现这个?
您需要解析查找文本并从这些部分构造正则表达式。首先,找到所有带有/"[^"]+"/g
的短语并去掉引号。接下来,从查找文本中删除短语,并通过空格分割查找所有剩余的单词:/s+/
。然后连接两个数组并连接以创建一个新的正则表达式,其中每个搜索项都包装在正向向前看语法中:(?=.*SearchTerm)
。最后,使用该正则表达式测试给定的文本是否匹配。下面是一个搜索函数:
function search(find, within) {
find = find.replace(/[*+?^$.[]{}()|\/]/g, "\$&");
var phrase = /"[^"]+"/g;
var phrases = find.match(phrase) || [];
phrases = $.map(phrases, function(s) {
return s.replace(/"/g, "");
});
var words = find.replace(phrase, "").split(/s+/);
var terms = words.concat(phrases);
var searchExpression = new RegExp("(?=.*" + terms.join(")(?=.*") + ").+", "i");
return searchExpression.test(within);
}
使用jQuery将其绑定到您的页面中:
$(function() {
$("#searchButton").click(function() {
var searchText = $("#searchInput").val();
$("p").removeClass("matchesSearch").filter(function() {
return search(searchText, $(this).text());
}).addClass("matchesSearch");
});
});
它在这里工作:http://jsfiddle.net/gilly3/DVxem/
Edit:也可以在这里工作,修复了转义regex元字符:http://jsfiddle.net/gilly3/DVxem/3/
基于IAbstractDownvoteFactory的框架代码:
var search = $('#text').val(),
filter;
if (search.match(/^"(.+)"$/)) {
search = search.match(/^"(.+)"$/)[1].toLowerCase();
filter = function() {
return $(this).text().toLowerCase().indexOf(search) != -1;
};
} else {
var words = search.split(" ");
filter = function() {
for (var i=0; i != words.length; i++) {
if ($(this).text().toLowerCase().indexOf(words[i]) == -1) {
return false;
}
}
return true;
}
}
$('p').css({color: 'black'}).filter(filter).css({
color: 'red'
});
演示:http://jsfiddle.net/kVUJj/3/