How can I implement a search using regex?
I have some elements:
<p>Windows Phone 7</p>
<p>W开发者_如何学运维indows Phone 7.5 "Mango"</p>
<p>Phone Windows 7</p>
- If I search for
Phone 7
it should return all results. - If I search for
7 Windows
it should return all results. - If I search for
"Phone Windows"
it should return only the last element.
Basically the user will input some text in an input
and I want to implement AND
and OR
with Regex.
How can I implement this?
You'll want to parse your find text and construct a regular expression from the parts. First, find all the phrases with /"[^"]+"/g
and strip off the quotes. Next, remove the phrases from the find text and find all the remaining words by splitting on whitespace: /\s+/
. Then concat your two arrays and join to create a new regular expression where each search term is wrapped in positive lookahead syntax: (?=.*SearchTerm)
. Finally, use that regular expression to test whether the given text matches. Here's a search function that does that:
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);
}
Tie it into your page with some jQuery:
$(function() {
$("#searchButton").click(function() {
var searchText = $("#searchInput").val();
$("p").removeClass("matchesSearch").filter(function() {
return search(searchText, $(this).text());
}).addClass("matchesSearch");
});
});
It works here: http://jsfiddle.net/gilly3/DVxem/
Edit: Works here too, with the fix to escape regex metacharacters: http://jsfiddle.net/gilly3/DVxem/3/
Based on the skeleton code by 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'
});
Demo: http://jsfiddle.net/kVUJj/3/
精彩评论