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


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

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


7436
2017-11-24 13:05


起源


使用indexOf方法很容易,你可以在这里看到indexOf和substring的教程: dreamsyssoft.com/javascript-shell-scripting/... - Triton Man
可能重复 JQuery字符串包含check - Saswat
你可以看到速度 r.indexOf(s) !== -1; 比其他人快。 hayageek.com/javascript-string-contains - Sherali Turdiyev
这里是检查字符串是否在字符串中的最常用方法的基准: jsben.ch/#/o6KmH - EscapeNetscape
视频在<5分钟内涵盖以下最佳选项,此处: youtube.com/watch?v=KENPi0xTgcE - ssmith


答案:


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

1.(ES6) includes - 去回答

var string = "foo",
    substring = "oo";
string.includes(substring);

2. ES5和更老 indexOf

var string = "foo",
    substring = "oo";
string.indexOf(substring) !== -1;

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

3。 search - 去回答

var string = "foo",
    expr = /oo/;
string.search(expr);

4. lodash包括 - 去回答

var string = "foo",
    substring = "oo";
_.includes(string, substring);

5. RegExp - 去回答

var string = "foo",
    expr = /oo/;  // no quotes here
expr.test(string);

6.匹配 - 去回答

var string = "foo",
    expr = /oo/;
string.match(expr);

性能测试 显示出来 indexOf 可能是最好的选择,如果它涉及速度问题。


11489
2017-12-30 04:23



@Steve indexOf 总是返回一个数字,所以不需要使用 !==。如果要保存字节,可以使用 ~'foo'.indexOf('oo') 如果找到子字符串,则返回truthy值,并返回虚假值(0)如果不是。 - Mathias Bynens
对于好奇:在两个恭维系统中,-1以二进制表示为全1(1111 1111 1111 1111 1111 1111 1111 1111为32位)。这里的按位反转(〜)都是零,或者只是零,因此是假的。这就是为什么波浪诡计有效,如果我必须自己这样说,那就太糟糕了。 - Adam Tolley
@SebNilsson你忘了包括 ~ 我在评论中建议的操作员。 ~'hello'.indexOf('h'); // -1, which is truthy但是 ~'hello'.indexOf('x'); // 0, which is falsy。 - Mathias Bynens
@ pramodc84那个链接指的是 Array 目的 indexOf 方法不到了 String 对象方法 - gion_13
@NicolasBarbulesco我相信所有看过我代码的人都会知道这一点 [["\t\n 987654321e-400"]] === 0 是假的。我不太相信看到我的代码的每个人都会知道这一点 [["\t\n 987654321e-432"]] == 0 是真的。 - kybernetikos


你可以轻松添加一个 contains 使用此语句的String方法:

String.prototype.contains = function(it) { return this.indexOf(it) != -1; };

注意: 请参阅下面的注释,了解不使用此参数的有效参数。我的建议:用你自己的判断。

或者:

if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; }

823
2017-11-24 14:17



不要修改您不拥有的对象。 nczonline.net/blog/2010/03/02/... - zachleat
@zachleat,在实践中可以理解。但是“foobar”.contains(“bar”)对规则来说是一个非常有用的例外。 - ndbroadbent
嗯,我的偏好是调整我的心理模型以适应JavaScript并只使用indexOf。它将使代码更容易理解下一个JavaScripter,并且必须阅读它。 - zachleat
if (typeof String.prototype.contains === 'undefined') { String.prototype.contains = function(it) { return this.indexOf(it) != -1; }; } - Pavel Hodek
如果你要经常使用这种indexOf,我最好使用这个函数。 @zachleat,我不同意使用indexOf比contains更具可读性。包含描述正在发生的事情,某些地方 indexOf() != -1 可能不那么透明。但是对每个人来说,只要你是一致的。 - smdrager


您的代码存在的问题是JavaScript区分大小写。你的方法调用

indexof()

应该是

indexOf()

尝试修复它,看看是否有帮助:

if (test.indexOf("title") !=-1) {
    alert(elm);
    foundLinks++;
}

429
2018-01-07 10:23



@JeremyW,我想在这一点上,这个答案的价值在于那些犯了同样错误的人(indexof 代替 indexOf)可以找到这个答案,看看发生了什么。我不会再触及这个问题了。 - Victor


有一个 string.includes 在ES6中

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

请注意,您可能需要加载 es6-shim 或者类似于在旧版浏览器上使用它。

require('es6-shim')

361
2017-11-24 13:06



因为我习惯于在其他语言中“包含”并且只是用它来实现我的功能,我只是遇到了错误。所以,关于支持的简短反馈。 Firefox 19 - OSX => OK,Firefox 19 - Windows => NOK,Chrome - OSX,Windows => NOK - Patrick Hammer
喜欢这个? String.prototype.contains = function (segment) { return this.indexOf(segment) !== -1; }; (顺便说一句:在原型上做事很糟糕) - Nijikokun
它不支持铬..... :( - Krunal Patel
@Norris它在ES6中。加载ES6垫片。你现在可以使用它。 - mikemaccana
.contains()和.includes()都是实验性的,非:非标准的。我不建议将它们用于生产系统。我现在坚持使用.indexOf()。 - Mike S.


var index = haystack.indexOf(needle);

341
2018-03-05 09:53





你可以使用JavaScript search() 方法。

语法是: string.search(regexp)

它返回匹配的位置,如果未找到匹配则返回-1。

见那里的例子: jsref_search

您不需要复杂的正则表达式语法。如果你不熟悉它们就简单了 st.search("title") 会做。如果您希望测试不区分大小写,那么您应该这样做 st.search(/title/i)


237
2017-10-21 05:31



这似乎比indexOf函数慢,因为它必须解析RegEx。但是,如果你想要一些不区分大小写的东西,那么你的方式就是你要走的路(我想),尽管那并不是我想要的。即使没有被问到,我也在投票 只是  因为 不区分大小写的选项。 - bgw
我没有运行基准测试,但会 str.toLowerCase().indexOf(searchstr.toLowerCase()) 对不区分大小写的搜索更有效率? - Tim S.
通过基准测试,结果发现搜索对于不区分大小写的搜索更有效。 jsperf.com/string-compare-perf-test 但是使用正则表达式搜索可能会很棘手,因为你需要逃避一些角色。 - misaxi
搜索可能会导致错误。正如misaxi所说,你必须逃脱一些角色。我使用搜索没有意识到参数预期正则表达式,并正在搜索管道字符。事实证明,任何字符串.search('|')== 0。 - James Foster
您可以使用escapeRegExp函数使serach文本安全。 function escapeRegExp(string){ return string.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1"); } 从 developer.mozilla.org/en/docs/Web/JavaScript/Guide/... - Mark


String.prototype.includes() 在ES6中引入。

确定是否可以在另一个字符串中找到一个字符串,   适当地返回true或false。

句法

var contained = str.includes(searchString [, position]);  

参数

searchString

要在此字符串中搜索的字符串。

position

此字符串中开始搜索的位置 searchString 默认为0。

var str = "To be, or not to be, that is the question.";

console.log(str.includes("To be"));    // true
console.log(str.includes("question")); // true
console.log(str.includes("To be", 1)); // false  

注意

这可能需要旧版浏览器中的ES6垫片。


167
2018-05-29 07:46



FWIW链接的MDN页面有一个简单的垫片/ polyfill: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Salman Abbas


如果你正在寻找一种替代方法来编写丑陋的-1检查,那么你可以先添加一个〜代替。

if (~haystack.indexOf('needle')) alert('found');

乔齐默尔曼  - 你会看到使用~on -1将其转换为0.数字0是a   falsey值,表示转换为false时将评估为false   一个布尔值。这可能看起来不是一个很大的洞察力,但是   记住,当查询不是时,indexOf之类的函数将返回-1   找到。这意味着不要写类似于此的东西:

if (someStr.indexOf("a") >= 0) {
  // Found it
} else  {
  // Not Found
}

您现在可以在代码中使用更少的字符,以便您可以编写它   喜欢这个:

if (~someStr.indexOf("a")) {
  // Found it
} else  {
  // Not Found
}

更多 详情请点击


120
2017-09-13 03:45



是的,现在我宁愿推荐使用ES6标准的polyfill includes() 通过以下方式: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... - Christian Landgren


这段代码应该运行良好:

var str="This is testing for javascript search !!!";
if(str.search("for") != -1) {
   //logic
} 

82
2017-12-13 20:05



它搜索传递的字符或单词,如果找到,则搜索返回一个整数值,该整数值是整个字符串中单词的位置。如果找不到单词或字符,则搜索函数返回-1。 - vaibhav


写一个常用的方法 contains JavaScript中的方法 是:

if (!String.prototype.contains) {
    String.prototype.contains = function (arg) {
        return !!~this.indexOf(arg);
    };
}

按位求反运算符(~)用来转 -1 成 0 (falsey),所有其他值都将为非零(真实)。

double boolean negation运算符用于将数字转换为布尔值。


77
2018-03-14 02:10



有什么好处 !!~ 过度 >-1? - alex
@alex,除了不依赖魔术数字之外没有任何特别的优势。使用你觉得舒服的东西。 - zzzzBov
@zzzzBov!~~同样依赖于幻数-1,以及它的按位表示是0的补码这一事实。 - Martijn
!!~this.indexOf(arg); 是不容易理解的,在上下文中也不是那么清楚。它还传达了这一事实 ~-1 是0,同意@Martijn。它也比简单的-1比较慢。但清晰度是主要因素。 - babinik
@Nick,我从未声称它是一个 好 方式,我只是说它是一个 共同 办法。就清晰度而言,我觉得这是为库保存几个字节的合理方法,但我倾向于使用 foo.indexOf('bar') > -1 - zzzzBov