简体   繁体   中英

How can search a string to see if it contains all substrings?

I will be using coffeescript/javascript/jquery and I need to return true if a string contains all of my substrings.

So, lets say that I have an array of substrings 'my', 'dog', 'spot'. I need to return a true if my string is 'growing up my pet dog was named spot'. But I would need to return false if the string was 'I had a dog named spot'.

I am thinking there is a way to do this with a regular expression, but can't seem to figure it out?

var mystring = "growing up my pet dog was named spot";
var words = ['my', 'dog', 'spot'];

var res = words.every(function(word) {
    return mystring.indexOf(word) !== -1;
});

If you want to reuse the function in various parts of your application, give it a name, and provide the string to be searched as the second argument, which makes it the this value.

function hasWordInString(word) {
    return this.indexOf(word) !== -1;
}

var res = words.every(hasWordInString, mystring);

The other nice thing about .every() is that it short-circuits if false is returned, so the search stops once a non-matching word is found, making it a little more efficient.


Force whole word matching

If you want to ensure that the matched string is a whole word to avoid "dog" matching "dogma" for example, you will need to make use of RegExp word boundaries:

function hasWordInString(word) {
    return this.match(new RegExp("\\b"+word+"\\b"))!=null;
}
var res = words.every(hasWordInString,mystring);

An alternate method for the books:

var str1 = "growing up my pet dog was named spot";
var str2 = "I had a dog named spot";
var words = ['my','dog','spot'];
function str_match_array(str,array)
{
    var found = array.filter(function(part) { return str.indexOf(part)>-1; });
    //Or using regex and word boundaries:
    var found = array.filter(function(part) { return str.match(new RegExp("\\b"+part+"\\b"))!=null; });
    return (found.length == array.length);
}
str_match_array(str1,words);//true
str_match_array(str2,words);//false

Using the .every method with regex to assert word boundaries:

function str_match_array(str,arr)
{
    return arr.every(function(part) {
                return str.match(new RegExp("\\b"+part+"\\b"))!=null;
            }); 
}
var result = str_match_array(str1,words);//true
var result = str_match_array(str2,words);//false

Right, if the array of substrings isn't a given:

words = words.forEach(function(word)
{
    return new RegExp(
        word.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),//escape
        'i'//optional, to make matches case-insensitive
    );
});
//for browsers that don't support forEach:
words = (function(words)
{//turn array of substrings into regex's
    for (var i=0;i<words.length;i++)
    {
        words[i] = new RegExp(
               words[i].replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"),
               'i'
        );
    }
    return words;
}(words));

Then, to match any substring:

function checkAll(string, patterns)
{
    patterns.forEach(function(pattern)
    {//or for loop for older browsers...
        if (!pattern.test(string))
        {//no match found
            return false;
        }
    }
    return true;
}
checkAll('growing up my pet dog was named spot', words);//true
checkAll('growing up my pet DOG was named Spot', words);//true
checkAll('the quick brown fox jumps over the lazy dog', words);//false

I got the char escaping regex I'm using to escape strings I'm passing to the RegExp constructor from here .

You don't need regular expression for this - just use indexOf, check for each words, and return if any of the words was not found

var check_string = function(string, words) {
    var count = 0;
    for (var i in words) {
      if (string.indexOf(words[i]) === -1) {
         return false;
      }
    }
    return true;
}
var ary=['my', 'dog', 'spot'];
var str="growing up my pet dog was named spot";
var temp="";

for(var i=0;i<ary.length;i++){

    temp=temp+".*(?:"+ary[i]+").*";

}

var regex= new RegExp(temp);
alert(regex.test(str));

http://jsfiddle.net/cgYTZ/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM