web-dev-qa-db-fra.com

Comment vérifier si une chaîne contient du texte provenant d'un tableau de sous-chaînes en JavaScript?

Assez simple. En javascript, je dois vérifier si une chaîne contient des sous-chaînes contenues dans un tableau.

99

Il n'y a rien d'intégré qui puisse le faire pour vous, vous devrez écrire une fonction pour cela.

Si vous savez _ les chaînes ne contiennent aucun des caractères spéciaux dans les expressions régulières, vous pouvez tricher un peu, comme ceci:

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

... qui crée une expression régulière qui est une série de alternations pour les sous-chaînes recherchées (par exemple, one|two) et qui teste s'il existe des correspondances pour l'une d'entre elles, mais Les sous-chaînes contiennent tous les caractères spéciaux dans les expressions rationnelles (*, [, etc.), vous devez d'abord les échapper et il vaut mieux faire la boucle ennuyeuse à la place.

Exemple live gratuit


Mettre à jour:

Dans un commentaire sur la question, Martin pose une question sur la nouvelle fonction Array#map dans ECMAScript5. map n’aide pas beaucoup, mais some est:

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

Exemple en direct (Ne fonctionne que sur les navigateurs modernes)

Remarquez que cela signifie un peu de surcharge, et vous ne l'avez que sur les implémentations conformes à ECMAScript5 (donc, pas IE7 ou une version antérieure, par exemple; peut-être même pas IE8), mais toujours si vous aimez vraiment ce style de programmation. (Vous pouvez aussi utiliser une cale ECMAScript5, celle-ci ou n’importe laquelle d’autres.)

142
T.J. Crowder
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
   }
}
46
raveren
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);
18
Jim Blackler

Solution à une ligne

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

Retourne true\false si la sous-chaîne exists\does'nt exist

Besoin du support ES6

11
Praveena

Pour les gens googler,

La réponse solide devrait être.

const substrings = ['connect', 'ready'];
const str = 'disconnect';
if (substrings.some(v => str === v)) {
   // Will only return when the `str` is included in the `substrings`
}
11
halfcube
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: Si l'ordre des tests n'a pas d'importance, vous pouvez utiliser ceci (avec une seule variable de boucle):

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]
    }
}
6
user

Si le tableau n'est pas grand, vous pouvez simplement boucler et vérifier la chaîne individuellement avec chaque sous-chaîne en utilisant indexOf(). Vous pouvez également créer une expression régulière avec des sous-chaînes comme alternatives, ce qui peut être ou ne pas être plus efficace.

2

Fonction Javascript permettant de rechercher un tableau de balises ou de mots-clés à l'aide d'une chaîne de recherche ou d'un tableau de chaînes de recherche. (Utilise ES5 une méthode de tableau et ES6 fonctions de flèche)

// 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;
}

Exemple d'utilisation:

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

Ce n’est pas que je suggère que vous étendiez/modifiiez le prototype de String, mais voici ce que j’ai fait:

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

1
akinuri

Si vous travaillez avec une longue liste de sous-chaînes composées de "mots" complets séparés par des espaces ou tout autre caractère commun, vous pouvez être un peu malin dans votre recherche.

Commencez par diviser votre chaîne en groupes de X, puis X + 1, puis X + 2, ..., jusqu'à Y. X et Y doivent correspondre au nombre de mots de votre sous-chaîne contenant le moins et le plus de mots, respectivement. Par exemple, si X est 1 et Y est 4, "Alpha Beta Gamma Delta" devient:

"Alpha" "Beta" "Gamma" "Delta"

"Alpha Beta" "Beta Gamma" "Gamma Delta"

"Alpha Beta Gamma" "Beta Gamma Delta"

"Alpha Beta Gamma Delta"

Si X est égal à 2 et Y égal à 3, vous omettez la première et la dernière ligne.

Vous pouvez maintenant rechercher rapidement dans cette liste si vous l'insérez dans un ensemble (ou une carte), beaucoup plus rapidement que par comparaison de chaînes.

L'inconvénient est que vous ne pouvez pas rechercher de chaînes comme "ta Gamm". Bien sûr, vous pourriez le permettre en séparant par caractère plutôt que par Word, mais vous auriez alors souvent besoin de créer un ensemble gigantesque et le temps/la mémoire dépensé dépasserait les avantages.

0
Emil Norén

C'est très tard, mais je viens de rencontrer ce problème. Dans mon propre projet, j’ai utilisé ce qui suit pour vérifier si une chaîne était dans un tableau:

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

De cette façon, vous pouvez prendre un tableau prédéfini et vérifier s'il contient une chaîne:

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

La meilleure réponse est ici: C'est également sensible à la casse

    var specsFilter = [.....];
    var yourString = "......";

    //if found a match
    if (specsFilter.some((element) => { return new RegExp(element, "ig").test(yourString) })) {
        // do something
    }
0
Adel Mourad

s'appuyant sur la réponse de T.J Crowder

en utilisant RegExp échappé pour tester "au moins une fois" l'occurrence d'au moins une des sous-chaînes.

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 ...'));

0
DhavalW

En utilisant underscore.js ou lodash.js, vous pouvez effectuer les opérations suivantes sur un tableau de chaînes:

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']

Et sur une seule corde:

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

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

// true
0
BuffMcBigHuge

Dessin de T.J. La solution de Crowder, j'ai créé un prototype pour traiter ce problème:

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