JavaScript:indexOf与搜索字符串时匹配?

ind*_*dra 64 javascript regex string client

除了可读性之外,使用之间是否存在任何可辨别的差异(可能性能)

str.indexOf("src") 
Run Code Online (Sandbox Code Playgroud)

str.match(/src/)
Run Code Online (Sandbox Code Playgroud)

我个人更喜欢match(和regexp),但同事似乎走了另一条路.我们想知道它是否重要......?

编辑:

我应该在一开始就说过,这是用于执行部分普通字符串匹配的函数(在JQuery的类属性中获取标识符),而不是使用通配符等进行完整的正则表达式搜索.

class='redBorder DisablesGuiClass-2345-2d73-83hf-8293' 
Run Code Online (Sandbox Code Playgroud)

所以它的区别在于:

string.indexOf('DisablesGuiClass-');
Run Code Online (Sandbox Code Playgroud)

VS

string.match(/DisablesGuiClass-/)
Run Code Online (Sandbox Code Playgroud)

Dav*_*ang 56

RegExp确实比indexOf慢(你可以在这里看到它),虽然通常这应该不是问题.使用RegExp,您还必须确保正确转义字符串,这是一个需要考虑的额外事项.

抛开这两个问题,如果两个工具完全符合您的需求,为什么不选择更简单的工具呢?

  • 根据这个jsperf测试,indexOf总是很快就很简单:http://stackoverflow.com/a/5296314/981933 (10认同)
  • @ 5arx,jsperf,就像jsfiddle一样,是快速测试想法的不可或缺的工具.这是一个公共站点,只需访问jsperf.com并创建自己的测试. (3认同)

Tim*_*ker 19

你的比较可能不完全公平.indexOf与纯字符串一起使用,因此非常快; match采取正则表达式 - 当然它可能比较慢,但如果你想做一个正则表达式匹配,你将不会走得太远indexOf.另一方面,正则表达式引擎可以进行优化,并且在过去几年中一直在提高性能.

在您的情况下,您正在寻找逐字字符串,indexOf应该足够了.但是仍然有一个正则表达式的应用程序:如果你需要匹配整个单词并且想要避免匹配子字符串,那么正则表达式会给你"单词边界锚点".例如:

indexOf('bar')
Run Code Online (Sandbox Code Playgroud)

会发现bar三次bar, fubar, barmy,而

match(/\bbar\b/)
Run Code Online (Sandbox Code Playgroud)

只有bar当它不是较长单词的一部分时才会匹配.

正如您在评论中看到的那样,已经进行了一些比较,表明正则表达式可能比速度快indexOf- 如果它的性能至关重要,您可能需要对代码进行概要分析.

  • 我认为这是一个公平的问题,来自Perl背景,等效的正则表达式比`indexOf`更快。 (2认同)

Yog*_*gaj 9

如果你想搜索的字符串出现不区分大小写match似乎比的组合更快indexOftoLowerCase()

点击这里 - http://jsperf.com/regexp-vs-indexof/152


Moh*_*lal 7

在这里,所有可能的方式(相对)搜索字符串

// 1.包含(在ES6中引入)

var string = "string to search for substring",
    substring = "sea";
string.includes(substring);
Run Code Online (Sandbox Code Playgroud)

// 2. string.indexOf

var string = "string to search for substring",
    substring = "sea";
string.indexOf(substring) !== -1;
Run Code Online (Sandbox Code Playgroud)

// 3. RegExp:测试

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

// 4. string.match

var string = "string to search for substring",
    expr = "/sea/";
string.match(expr);
Run Code Online (Sandbox Code Playgroud)

// 5。字符串搜索

var string = "string to search for substring",
    expr = "/sea/";
string.search(expr);
Run Code Online (Sandbox Code Playgroud)

这是一个src:https//koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31

基准似乎专门针对es6 include而扭曲,请阅读注释。

在简历中:

如果您不需要比赛。=>您要么需要正则表达式,然后使用test。否则,es6 includeindexOf。仍然测试 vs indexOf接近。

对于包括vs indexOf:

他们似乎是相同的:https://jsperf.com/array-indexof-vs-includes/4 (如果它是不同的,将是奇怪的,他们大多是执行相同的除了不同,他们公开检查这个

并进行我自己的基准测试。此处是http://jsben.ch/fFnA0。 您可以对其进行测试(取决于浏览器)[测试多次],在这里它的性能如何(多次运行indexOf并包含一个节拍,另一个节拍,并且它们很接近)。所以他们是一样的。[此处使用与以上文章相同的测试平台]。

在此处输入图片说明 在此处输入图片说明

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

在此处输入图片说明

同时测试了chrome和firefox。

请注意,jsben.ch无法处理内存溢出(或有正确的限制。它不会显示任何消息),因此,如果您添加了8个以上的文本重复项(8个工作正常),结果可能会出错。但是结论是,对于非常大的文本,这三个函数都以相同的方式执行。否则,对于短的indexOf和include是相同的,并且测试要慢一些。或可以与Chrome中的外观相同(firefox 60较慢)。

注意jsben.ch:如果结果不一致,请不要惊慌。尝试其他时间,看看是否一致。更改浏览器,有时它们只是完全错误地运行。错误或错误的内存处理。或者其他的东西。

例如:

在此处输入图片说明

这也是我在jsperf上的基准测试(更好的详细信息,并为多个浏览器处理图表)

(顶部是铬)

普通文本 https://jsperf.com/indexof-vs-includes-vs-test-2019
简历: include和indexOf具有相同的性能。测试较慢。

在此处输入图片说明 在此处输入图片说明 (似乎所有三个在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/
简历:包括和的indexOf执行相同和测试慢。

在此处输入图片说明

注意:关于上述基准。对于非常短的字符串版本(jsperf),chrome有很大的错误。以我的眼神来看。两个indexOf都运行了大约60个样本,并且包含相同的方式(重复了很多次)。并测试得少一点,那么慢。不要被错误的图表所迷惑。显然是错误的。对于Firefox,相同的测试工作还可以,当然这是一个错误。

此处为插图:(第一个图像是对Firefox的测试) 在此处输入图片说明 哇啊。突然indexOf成为超人。但是正如我说的,我做了测试,并查看了大约60个样本。indexOf和include以及它们执行相同的操作。jspref上的错误。除了这一点(可能是由于与内存限制有关的问题)之外,其余所有内容都是一致的,它提供了更多细节。您会实时看到多少简单的事情发生。

最终简历

indexOf vs includes =>性能相同

测试 =>对于短字符串或文本可能会更慢。与长文本相同。对于正则表达式引擎增加的开销,这是有意义的。在Chrome中,这似乎没有任何关系。


小智 6

你问是否str.indexOf('target')str.match(/target/)应该是首选.正如其他海报所建议的那样,这些方法的用例和返回类型是不同的.第一个问" str我能在哪里找到'target'?" 第二个问"确实str匹配正则表达式,如果是这样,任何相关的捕获组的所有匹配是什么?"

问题是,在技术上没有一个设计用于提出更简单的问题"字符串是否包含子字符串?" 有明确设计的东西:

var doesStringContainTarget = /target/.test(str);
Run Code Online (Sandbox Code Playgroud)

使用有几个好处regex.test(string):

  1. 它返回一个布尔值,这是你关心的
  2. 它比str.match(/target/)(和竞争对手str.indexOf('target'))更高效
  3. 如果由于某种原因,strundefinednull,你会得到false(期望的结果),而不是扔一个TypeError


Luk*_*keH 5

indexOf理论上,当你只是搜索一些纯文本时,使用should应该比正则表达式更快,但如果你关心性能,你应该自己做一些比较基准测试.

如果您愿意match并且它足够快以满足您的需求,那就去吧.

对于它的价值,我同意你的同事:我indexOf在搜索普通字符串时使用,match只有当我需要正则表达式提供的额外功能时才使用.