在JavaScript中如何检查字符串是否包含子字符串

在JavaScript中如何检查字符串是否包含子字符串

技术背景

在JavaScript开发中,经常需要检查一个字符串是否包含另一个子字符串。随着ECMAScript版本的更新,有不同的方法可以实现这一需求。

实现步骤

使用 String.prototype.includes(ECMAScript 6及以上)

String.prototype.includes 是ES6引入的方法,用于检查字符串是否包含指定的子字符串。该方法区分大小写,并且在没有polyfill的情况下,Internet Explorer不支持该方法。

1
2
3
const string = "foo";
const substring = "oo";
console.log(string.includes(substring)); // true

使用 String.prototype.indexOf(ECMAScript 5及以下)

在ES5或更旧的环境中,可以使用 String.prototype.indexOf 方法。当子字符串未找到时,该方法返回 -1。

1
2
3
var string = "foo";
var substring = "oo";
console.log(string.indexOf(substring) !== -1); // true

使用polyfill支持旧浏览器

如果需要在不支持ES6的旧浏览器中使用 String.prototype.includes,可以使用polyfill。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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;
}
};
}

使用KMP算法

KMP(Knuth–Morris–Pratt)算法是一种高效的字符串匹配算法,在最坏情况下的时间复杂度为O(n + m),其中n是字符串的长度,m是子字符串的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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

最佳实践

  • 如果项目支持ES6及以上环境,优先使用 String.prototype.includes,因为它的代码更简洁易读。
  • 如果需要兼容旧浏览器,可以使用 String.prototype.indexOf 或添加polyfill。
  • 如果对最坏情况下的时间复杂度有要求,并且字符串和子字符串较长,可以考虑使用KMP算法。

常见问题

  • 兼容性问题String.prototype.includes 在旧浏览器中可能不支持,需要使用polyfill。
  • 大小写问题String.prototype.includesString.prototype.indexOf 都是区分大小写的,如果需要不区分大小写的匹配,需要先将字符串和子字符串都转换为相同的大小写。

在JavaScript中如何检查字符串是否包含子字符串
https://119291.xyz/posts/how-to-check-string-contains-substring-in-javascript/
作者
ww
发布于
2025年5月7日
许可协议