javascriptjqueryregex

How can I implement a search using regex?


I have some elements:

<p>Windows Phone 7</p>
<p>Windows 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?


Solution

  • 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/