JavaScript:搜索字符串时indexOf与Match?[已关闭]

egdjgwm8  于 12个月前  发布在  Java
关注(0)|答案(9)|浏览(112)

已关闭。此问题为opinion-based。目前不接受回答。
**要改进此问题吗?**更新此问题,以便editing this post可以使用事实和引文来回答。

4天前关闭。
社区在4天前审查了是否重新打开此问题,并将其关闭:
原始关闭原因未解决
Improve this question
在使用

str.indexOf("src")

字符串

str.match(/src/)


我个人更喜欢match(和regexp),但同事们似乎走了另一条路。我们想知道这是否重要...?
编辑:
我应该在一开始就说,这是针对那些将进行部分纯字符串匹配(为JQuery提取类属性中的标识符)而不是使用通配符等进行完整的regexp搜索的函数。

class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'


所以这是以下两种情况的区别:

string.indexOf('DisablesGuiClass-');


string.match(/DisablesGuiClass-/)

zlhcx6iw

zlhcx6iw1#

RegExp确实比indexOf慢(你可以看到它是here),虽然通常这不应该是一个问题。使用RegExp,你还必须确保字符串被正确转义,这是一个额外的事情要考虑。
抛开这两个问题不谈,如果两个工具都能满足您的需求,为什么不选择更简单的一个呢?

vi4fp9gy

vi4fp9gy2#

这里所有可能的方式(相对)搜索字符串
// 1. includes(在ES6中引入)

var string = "string to search for substring",
    substring = "sea";
string.includes(substring);

字符串
// 2. string.indexOf

var string = "string to search for substring",
    substring = "sea";
string.indexOf(substring) !== -1;


// 3. RegExp:test

var string = "string to search for substring",
    expr = /sea/;  // no quotes here
expr.test(string);


// 4. string.match

var string = "string to search for substring",
    expr = "/sea/";
string.match(expr);


//5. string.search

var string = "string to search for substring",
    expr = "/sea/";
string.search(expr);


这里有一个src:https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
基准似乎是扭曲特别是为es6包括,阅读评论。

简历中:

如果你不需要匹配。=>要么你需要正则表达式,所以使用test。否则es6includesindexOf。仍然testvsindexOf很接近。

对于includes vs indexOf:

它们似乎是相同的:https://jsperf.com/array-indexof-vs-includes/4(如果它是不同的,这将是wierd,他们大多执行相同的,除了他们暴露check this的差异)
对于我自己的基准测试.这里是http://jsben.ch/fFnA0你可以测试它(它的浏览器依赖)[测试多次]这里它是如何执行的(多次运行indexOf和包括一个击败其他,他们是接近).所以他们是一样的. [这里使用相同的测试平台作为上述文章].

这里是一个长文本版本(8倍长)http://jsben.ch/wSBA2



测试了Chrome和Firefox,同样的事情。
注意jsben.ch不处理内存溢出(或者有限制。它不显示任何消息),所以如果你添加超过8个文本重复(8个工作正常),结果可能会出错。但结论是对于非常大的文本,所有三个都以相同的方式执行。否则,对于短的indexOf和includes是相同的,测试有点慢。或者可以与Chrome中的相同(火狐60更慢)。
注意jsben.ch:如果你得到不一致的结果,不要惊慌。尝试不同的时间,看看它是否一致。改变浏览器,有时他们只是运行完全错误。错误或内存处理不好。或其他东西。
例如:



这里也是我对jsperf的基准测试(更好的细节,并处理多个浏览器的图形)
(top是Chrome)

普通文本https://jsperf.com/indexof-vs-includes-vs-test-2019
**resume:**includes和indexOf性能相同,测试慢一点。

x1c4d 1xx 1c 5d 1x(似乎所有三个在chrom中执行相同)

长文本(比正常文本长12倍)https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
**简历:**三个都是一样的。(Chrome和Firefox)

非常短的字符串https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
**resume:**includes和indexOf执行相同,测试较慢。

注意事项:关于上面的基准测试。对于very short string版本(jsperf),Chrome有一个很大的错误。通过我的眼睛看到。大约60个样本以同样的方式运行indexOf和includes(重复了很多次)。测试少一点,所以慢一点。不要被错误的图表愚弄。它显然是错误的。同样的测试工作对Firefox来说是好的,肯定是一个bug。
这里的插图:(第一张图片是在firefox上的测试)

watcher.突然indexOf变成了超人.但正如我所说,我做了测试,并在样本的数量约为60.两个indexOf和包括,他们执行相同.一个错误上jspref.除了这一个(可能是因为内存限制相关的问题)所有其余的都是一致的,它给予更多的细节。你可以看到有多少简单的发生在真实的时间。

最终简历

indexOf vs includes=>相同性能
test=>对于短字符串或文本可能会慢一些。对于长文本也是一样。这对正则表达式引擎增加的开销是有意义的。在Chrome中,这似乎根本不重要。

km0tfn4u

km0tfn4u3#

indexOf使用普通字符串,因此速度非常快; match使用正则表达式-当然,相比之下,它可能会慢一些,但如果你想进行正则表达式匹配,使用indexOf不会太远。另一方面,正则表达式引擎可以优化,并且在过去几年中一直在提高性能。
在你的例子中,你正在寻找一个逐字字符串,indexOf应该足够了。但是正则表达式仍然有一个应用:如果你需要匹配 * 整个 * 单词,并且希望避免匹配子字符串,那么正则表达式给予你“单词边界锚”。例如:

indexOf('bar')

字符串
将在bar, fubar, barmy中找到bar三次,而

match(/\bbar\b/)


仅当bar不是较长单词的一部分时才匹配。
正如你在评论中看到的,一些比较表明正则表达式可能比indexOf快-如果它是性能关键的,你可能需要分析你的代码。

wf82jlnq

wf82jlnq4#

如果你试图搜索子字符串出现不区分大小写,那么match似乎比indexOftoLowerCase()的组合更快。
点击此处-http://jsperf.com/regexp-vs-indexof/152

2ul0zpep

2ul0zpep5#

您会问,应该首选str.indexOf('target')还是str.match(/target/)。正如其他发帖者所建议的那样,这些方法的用例和返回类型是不同的。第一个问题是“在str中的哪里可以首先找到'target'?”第二个问题是“str是否与正则表达式匹配,如果匹配,则任何关联的捕获组的所有匹配项是什么?”
问题是,从技术上讲,这两个问题都不是为了问“字符串是否包含子字符串?”这个简单的问题而设计的,而是为了这样做而设计的:

var doesStringContainTarget = /target/.test(str);

字符串
使用regex.test(string)有几个优点:
1.它返回一个布尔值,这是您所关心的
1.它的性能高于str.match(/target/)(与str.indexOf('target')竞争)
1.如果出于某种原因,strundefinednull,则将得到false(所需结果),而不是抛出TypeError

of1yzvn4

of1yzvn46#

从理论上讲,当你只是搜索一些纯文本时,使用indexOf应该比正则表达式快,但是如果你关心性能的话,你应该自己做一些比较基准测试。
如果你更喜欢match,并且它的速度足够快,那么就去做吧。
无论如何,我同意你的同事的观点:当搜索普通字符串时,我会使用indexOf,只有当我需要正则表达式提供的额外功能时,才使用match等。

t9eec4r0

t9eec4r07#

从性能上看,indexOf至少会比match稍微快一点。这一切都取决于具体的实现。在决定使用哪一个时,请问自己以下问题:
一个整数索引就足够了,还是我需要一个RegExp匹配结果的功能?

d7v8vwbk

d7v8vwbk8#

返回值不同

除了其他答案中提到的性能影响之外,重要的是要注意每个方法的返回值是不同的;因此,方法不能仅仅被替换而不改变逻辑。

调用String对象中指定值的第一个匹配项的索引,从fromIndex开始搜索。

  • 如果未找到值,则返回-1。*

一个数组,包含整个匹配结果和任何括号捕获的匹配结果。

  • 如果没有匹配项,则返回null *。

因为.indexOf返回0,如果调用字符串 * 以指定的值开始 *,简单的truthy测试将失败。

    • 例如:**
  • 在这堂课上 *
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'

字符串

  • .每个的返回值会有所不同:*
//  returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
    … // this block is skipped.
}

  • 对比 *
//  returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) { 
    … // this block is run.
}


使用.indexOf的返回值运行truthy测试的正确方法是针对-1进行测试:

if (string.indexOf('DisablesGuiClass-') !== -1) {
//  ^returns `0`                        ^evaluates to `true`
    … // this block is run.
}

b09cbbtk

b09cbbtk9#

记住Internet Explorer 8不理解indexOf。但是如果你的用户中没有人使用ie8(谷歌分析会告诉你),那么忽略这个答案。修复ie8的可能解决方案:How to fix Array indexOf() in JavaScript for Internet Explorer browsers

相关问题