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

gra*_*amm 7430 javascript string substring string-matching

通常我会期待一种String.contains()方法,但似乎没有一种方法.

检查这个的合理方法是什么?

Fab*_*ger 13309

以下列出了当前的可能性:

1.(ES6)String.prototype.includes - 去回答(没有IE支持)

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

console.log(string.includes(substring));
Run Code Online (Sandbox Code Playgroud)

2. ES5和更老 includes

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

console.log(string.indexOf(substring) !== -1);
Run Code Online (Sandbox Code Playgroud)

String.prototype.indexOf返回另一个字符串中字符串的位置.如果没有找到,它将返回String.prototype.includes.

3.includes - 去回答

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

console.log(string.includes(substring));
Run Code Online (Sandbox Code Playgroud)

4. lodash包括 - 去回答

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

console.log(string.indexOf(substring) !== -1);
Run Code Online (Sandbox Code Playgroud)

5. RegExp - 去回答

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

console.log(string.includes(substring));
Run Code Online (Sandbox Code Playgroud)

6.匹配 - 去回答

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

console.log(string.indexOf(substring) !== -1);
Run Code Online (Sandbox Code Playgroud)

性能测试显示String.prototype.indexOf可能是最佳选择,如果它涉及速度问题.

  • 为什么这里还要讨论区分大小写的问题? (13认同)
  • @Gavin 默认情况下,如果我想知道某个东西是否是子字符串,我想它会区分大小写。毕竟“A”和“a”是不同的字符。OP从未要求“不区分大小写”搜索(如果你将所有内容都设为小写,这是一个简单的解决方案) (11认同)
  • @Aashiq:是的,空字符串是每个字符串的子字符串。 (9认同)
  • 我也不喜欢IE,但是如果您有两个功能基本相同,并且其中一个功能比另一个功能更好,那么我认为您应该选择一个更好支持的功能?所以`indexOf()`是... (6认同)
  • `string.toUpperCase()。includes(substring.toUpperCase())` (5认同)
  • 虽然这是一个很好的答案,并且OP从未要求进行“区分大小写”搜索,但应该注意的是“includes”执行[区分大小写](https://developer.mozilla.org/en-US /docs/Web/JavaScript/Reference/Global_Objects/String/includes) 搜索。 (4认同)
  • `indexOf` 也是区分大小写的搜索,因此 `includes` 和 `indexOf` 都是区分大小写的。 (2认同)

eli*_*ocs 500

String.prototype.includesES6中有一个:

"potato".includes("to");
> true
Run Code Online (Sandbox Code Playgroud)

请注意,您可能需要加载String.prototype.includes或类似才能在旧版浏览器上使用它.

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;
    }
  };
}
Run Code Online (Sandbox Code Playgroud)

  • 只需执行“ potato” .includes(“ to”);`并通过Babel运行它。 (2认同)
  • 此外,对“number”的检查也无法像“includes”那样执行。示例:es6 include 对于 `"abc".includes("ab", "1")` 返回 false,这个 polyfill 将返回 true (2认同)

wz3*_*366 23

另一种选择是KMP(Knuth–Morris–Pratt)。

与单纯算法O(nm)的最坏情况相比,KMP算法在最坏情况的O(n + m)时间中搜索长度为n的字符串中的长度为m的子字符串,因此使用KMP可能会如果您担心最坏的情况下的时间复杂度,则是合理的。

这是Nayuki项目的JavaScript实现,取自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.
Run Code Online (Sandbox Code Playgroud)

// 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.
Run Code Online (Sandbox Code Playgroud)

  • 不质疑这种方法的任何内容......但为什么要在表上有“includes”或“indexOf”的地方实施 KMP。(虽然那些可能使用 KMP 的底层隐含......不确定) (10认同)
  • 99% 的情况下,这样做对于软件项目的非计算方面来说是矫枉过正且有害的。除非你正在做一些极其关键的事情,否则我强烈建议不要走这条路……我不认为像 Twitter、Facebook 或大多数 Google 产品这样的大公司会使用这个……那你为什么要这么做呢? (5认同)
  • 如果这是为了提高速度,如果您用“[i]”替换“.charAt(i)”以避免额外的函数调用,它可能会运行得更快。 (3认同)
  • KMP 在这里提供线性 O(n) 性能。 (2认同)