Wie überprüfe ich, ob eine Zeichenfolge eine Teilzeichenfolge in JavaScript enthält?

7427

Normalerweise würde ich eine String.contains()Methode erwarten , aber es scheint keine zu geben.

Was ist ein vernünftiger Weg, um dies zu überprüfen?

Peter O.
quelle

Antworten:

13774

ECMAScript 6 eingeführt String.prototype.includes:

const string = "foo";
const substring = "oo";

console.log(string.includes(substring));

includes hat jedoch keine Internet Explorer-Unterstützung . Verwenden Sie in Umgebungen mit ECMAScript 5 oder älteren Versionen, String.prototype.indexOfdie -1 zurückgeben, wenn eine Teilzeichenfolge nicht gefunden werden kann:

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

console.log(string.indexOf(substring) !== -1);

Ry-
quelle
25
Ich mag IE auch nicht, aber wenn Sie zwei Funktionen haben, die weitgehend identisch sind und eine besser unterstützt wird als die andere, sollten Sie die besser unterstützte auswählen? So ist indexOf()es ...
rob74
3
Ist es möglich, eine Suche ohne Berücksichtigung der Groß- und Kleinschreibung durchzuführen?
Eric McWinNEr
18
string.toUpperCase().includes(substring.toUpperCase())
Rodrigo Pinto
2
@EricMcWinNEr /regexpattern/i.test(str)-> i Flag steht für Groß- und Kleinschreibung
Code Maniac
Dies scheint bei mir in Google App Script nicht zu funktionieren.
Ryan
559

Es gibt eine String.prototype.includesin ES6 :

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

Beachten Sie, dass dies in Internet Explorer oder anderen alten Browsern ohne oder mit unvollständiger ES6-Unterstützung nicht funktioniert . Damit es in alten Browsern funktioniert, möchten Sie möglicherweise einen Transpiler wie Babel , eine Shim-Bibliothek wie es6-shim oder diese Polyfüllung von MDN verwenden :

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;
    }
  };
}
Elioks
quelle
3
Mach "potato".includes("to");es einfach und lass es durch Babel laufen.
Derk Jan Speelman
1
Includes wird von IE leider nicht unterstützt
Sweet Chilly Philly
@eliocs können Sie dies beantworten. Ich bekomme eine Nachricht. Die Nachricht muss
geändert werden
1
Ein weiteres Plus ist, dass auch zwischen Groß- und Kleinschreibung unterschieden wird. "boot".includes("T")istfalse
Jonatas CD
47

Eine andere Alternative ist KMP (Knuth-Morris-Pratt).

Der KMP-Algorithmus sucht im ungünstigsten Fall O ( n + m ) nach einer Länge- m- Teilzeichenfolge in einer Länge- n- Zeichenfolge im Vergleich zu einem Worst-Fall von O ( nm ) für den naiven Algorithmus, sodass möglicherweise KMP verwendet wird Seien Sie vernünftig, wenn Sie sich für die Komplexität der Worst-Case-Zeit interessieren.

Hier ist eine JavaScript-Implementierung von Project Nayuki aus 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
}

console.log(kmpSearch('ays', 'haystack') != -1) // true
console.log(kmpSearch('asdf', 'haystack') != -1) // false

Mark Amery
quelle
11
Dies ist übertrieben, aber dennoch eine interessante Antwort
Faissaloo