web-dev-qa-db-fra.com

Comment vérifier si une chaîne contient une sous-chaîne en JavaScript?

En général, je m'attendrais à une méthode String.contains(), mais il ne semble pas en avoir.

Quel est un moyen raisonnable de vérifier cela?

7434
gramm

String # includes ()

ES6 introduit String.prototype.includes :

var string = "foo",
    substring = "oo";

string.includes(substring)

includesn’a pas le support IE , cependant.

String # indexOf ()

Dans un environnement ES5 ou antérieur, String.prototype.indexOf renvoie l'index d'une sous-chaîne (ou -1 si introuvable):

var string = "foo",
    substring = "oo";

string.indexOf(substring) !== -1

RegExp # test ()

Les utilisateurs plus avancés peuvent préférer RegExp # test , ce qui permet de tester des expressions régulières:

var string = "foo",
    regex = /oo/;

regex.test(string);
12770
Fabien Ménager

Il y a un String.prototype.includes dans ES6 :

"potato".includes("to");
> true

Notez que ceci ne fonctionne pas dans Internet Explorer ou certains anciens navigateurs avec un support ES6 inexistant ou incomplet. Pour que cela fonctionne dans les anciens navigateurs, vous pouvez utiliser un transpiler tel que Babel , une bibliothèque de shim telle que es6-shim , ou this polyfill de MDN :

if (!String.prototype.includes) {
  String.prototype.includes = function(search, start) {
    'use strict';
    if (typeof start !== 'number') {
      start = 0;
    }

    if (start + search.length > this.length) {
      return false;
    } else {
      return this.indexOf(search, start) !== -1;
    }
  };
}
452
eliocs

Une autre alternative est KMP .

L'algorithme KMP recherche une longueur - m sous-chaîne dans une longueur - n chaîne dans le pire des cas O ( n + m ) time, par rapport au pire cas de O ( n m ) pour le algorithme naïf, l’utilisation de KMP peut donc être raisonnable si vous vous souciez de la complexité temporelle dans le pire des cas.

Voici une implémentation JavaScript par Project Nayuki, extraite de https://www.nayuki.io/res/knuth-morris-pratt-string-matching/kmp-string-matcher.js :

// Searches for the given pattern string in the given text string using the Knuth-Morris-Pratt string matching algorithm.
// If the pattern is found, this returns the index of the start of the earliest match in 'text'. Otherwise -1 is returned.
function kmpSearch(pattern, text) {
    if (pattern.length == 0)
        return 0;  // Immediate match

    // Compute longest suffix-prefix table
    var lsp = [0];  // Base case
    for (var i = 1; i < pattern.length; i++) {
        var j = lsp[i - 1];  // Start by assuming we're extending the previous LSP
        while (j > 0 && pattern.charAt(i) != pattern.charAt(j))
            j = lsp[j - 1];
        if (pattern.charAt(i) == pattern.charAt(j))
            j++;
        lsp.Push(j);
    }

    // Walk through text string
    var j = 0;  // Number of chars matched in pattern
    for (var i = 0; i < text.length; i++) {
        while (j > 0 && text.charAt(i) != pattern.charAt(j))
            j = lsp[j - 1];  // Fall back in the pattern
        if (text.charAt(i) == pattern.charAt(j)) {
            j++;  // Next char matched, increment position
            if (j == pattern.length)
                return i - (j - 1);
        }
    }
    return -1;  // Not found
}

Exemple d'utilisation:

kmpSearch('ays', 'haystack') != -1 // true
kmpSearch('asdf', 'haystack') != -1 // false
9
wz366