开发者

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>
  1. If I search for Phone 7 it should return all results.
  2. If I search for 7 Windows it should return all results.
  3. 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/

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜