¿Cómo comprobar si una cadena contiene una subcadena en JavaScript?
Normalmente esperaría un String.contains()
método, pero no parece haber ninguno.
¿Cuál es una forma razonable de comprobar esto?
ECMAScript 6 introducido String.prototype.includes
:
const string = "foo";
const substring = "oo";
console.log(string.includes(substring)); // true
String.prototype.includes
distingue entre mayúsculas y minúsculas y no es compatible con Internet Explorer sin un polyfill .
En ECMAScript 5 o entornos anteriores, utilice String.prototype.indexOf
, que devuelve -1 cuando no se puede encontrar una subcadena:
var string = "foo";
var substring = "oo";
console.log(string.indexOf(substring) !== -1); // true
Hay un String.prototype.includes
en ES6 :
"potato".includes("to");
> true
Tenga en cuenta que esto no funciona en Internet Explorer ni en otros navegadores antiguos sin soporte ES6 o incompleto. Para que funcione en navegadores antiguos, es posible que desees utilizar un transpilador como Babel , una biblioteca shim como es6-shim o este 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;
}
};
}
Otra alternativa es KMP (Knuth-Morris-Pratt).
El algoritmo KMP busca una subcadena de longitud m en una cadena de longitud n en el peor de los casos O( n + m ), en comparación con el peor de los casos de O( n ⋅ m ) para el algoritmo ingenuo, por lo que usar KMP puede Sea razonable si le importa la complejidad del tiempo en el peor de los casos.
Aquí hay una implementación de JavaScript del Proyecto Nayuki, tomada 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[i] !== pattern[j])
j = lsp[j - 1];
if (pattern[i] === pattern[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[i] != pattern[j])
j = lsp[j - 1]; // Fall back in the pattern
if (text[i] == pattern[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