How to check if a string contains text from an arr

2019-01-06 10:04发布

问题:

Pretty straight forward. In javascript, I need to check if a string contains any substrings held in an array.

回答1:

There's nothing built-in that will do that for you, you'll have to write a function for it.

If you know the strings don't contain any of the characters that are special in regular expressions, then you can cheat a bit, like this:

if (new RegExp(substrings.join("|")).test(string)) {
    // At least one match
}

...which creates a regular expression that's a series of alternations for the substrings you're looking for (e.g., one|two) and tests to see if there are matches for any of them, but if any of the substrings contains any characters that are special in regexes (*, [, etc.), you'd have to escape them first and you're better off just doing the boring loop instead.

Gratuitous live example


Update:

In a comment on the question, Martin asks about the new Array#map function in ECMAScript5. map isn't all that much help, but some is:

if (substrings.some(function(v) { return str.indexOf(v) >= 0; })) {
    // There's at least one
}

Live example (Only works on modern browsers)

Mind you, it does mean some overhead, and you only have it on ECMAScript5-compliant implementations (so, not IE7 or earlier, for instance; maybe not even IE8), but still if you're really into that style of programming... (And you could use an ECMAScript5 shim, this one or any of several others.)



回答2:

var yourstring = 'tasty food'; // the string to check against


var substrings = ['foo','bar'],
    length = substrings.length;
while(length--) {
   if (yourstring.indexOf(substrings[length])!=-1) {
       // one of the substrings is in yourstring
   }
}


回答3:

function containsAny(str, substrings) {
    for (var i = 0; i != substrings.length; i++) {
       var substring = substrings[i];
       if (str.indexOf(substring) != - 1) {
         return substring;
       }
    }
    return null; 
}

var result = containsAny("defg", ["ab", "cd", "ef"]);
console.log("String was found in substring " + result);


回答4:

For people Googling,

The solid answer should be.

const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
   // Will only return when the `str` is included in the `substrings`
}


回答5:

One line solution

substringsArray.some(substring=>yourBigString.includes(substring))

Returns true\false if substring exists\does'nt exist

Needs ES6 support



回答6:

var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = 0, len = arr.length; i < len; ++i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}

edit: If the order of the tests doesn't matter, you could use this (with only one loop variable):

var str = "texttexttext";
var arr = ["asd", "ghj", "xtte"];
for (var i = arr.length - 1; i >= 0; --i) {
    if (str.indexOf(arr[i]) != -1) {
        // str contains arr[i]
    }
}


回答7:

If the array is not large, you could just loop and check the string against each substring individually using indexOf(). Alternatively you could construct a regular expression with substrings as alternatives, which may or may not be more efficient.



回答8:

Javascript function to search an array of tags or keywords using a search string or an array of search strings. (Uses ES5 some array method and ES6 arrow functions)

// returns true for 1 or more matches, where 'a' is an array and 'b' is a search string or an array of multiple search strings
function contains(a, b) {
    // array matches
    if (Array.isArray(b)) {
        return b.some(x => a.indexOf(x) > -1);
    }
    // string match
    return a.indexOf(b) > -1;
}

Example usage:

var a = ["a","b","c","d","e"];
var b = ["a","b"];
if ( contains(a, b) ) {
    // 1 or more matches found
}


回答9:

Using underscore.js or lodash.js, you can do the following on an array of strings:

var contacts = ['Billy Bob', 'John', 'Bill', 'Sarah'];

var filters = ['Bill', 'Sarah'];

contacts = _.filter(contacts, function(contact) {
    return _.every(filters, function(filter) { return (contact.indexOf(filter) === -1); });
});

// ['John']

And on a single string:

var contact = 'Billy';
var filters = ['Bill', 'Sarah'];

_.every(filters, function(filter) { return (contact.indexOf(filter) >= 0); });

// true


回答10:

Not that I'm suggesting that you go and extend/modify String's prototype, but this is what I've done:

String.prototype.includes()

String.prototype.includes = function (includes) {
    console.warn("String.prototype.includes() has been modified.");
    return function (searchString, position) {
        if (searchString instanceof Array) {
            for (var i = 0; i < searchString.length; i++) {
                if (includes.call(this, searchString[i], position)) {
                    return true;
                }
            }
            return false;
        } else {
            return includes.call(this, searchString, position);
        }
    }
}(String.prototype.includes);

console.log('"Hello, World!".includes("foo");',          "Hello, World!".includes("foo")           ); // false
console.log('"Hello, World!".includes(",");',            "Hello, World!".includes(",")             ); // true
console.log('"Hello, World!".includes(["foo", ","])',    "Hello, World!".includes(["foo", ","])    ); // true
console.log('"Hello, World!".includes(["foo", ","], 6)', "Hello, World!".includes(["foo", ","], 6) ); // false



回答11:

This is super late, but I just ran into this problem. In my own project I used the following to check if a string was in an array:

["a","b"].includes('a')     // true
["a","b"].includes('b')     // true
["a","b"].includes('c')     // false

This way you can take a predefined array and check if it contains a string:

var parameters = ['a','b']
parameters.includes('a')    // true


回答12:

building on T.J Crowder's answer

using escaped RegExp to test for "at least once" occurrence, of at least one of the substrings.

function buildSearch(substrings) {
  return new RegExp(
    substrings
    .map(function (s) {return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');})
    .join('{1,}|') + '{1,}'
  );
}


var pattern = buildSearch(['hello','world']);

console.log(pattern.test('hello there'));
console.log(pattern.test('what a wonderful world'));
console.log(pattern.test('my name is ...'));



回答13:

Drawing from T.J. Crowder's solution, I created a prototype to deal with this problem:

Array.prototype.check = function (s) {
  return this.some((v) => {
    return s.indexOf(v) >= 0;
  });
};