除了可读性之外,使用
之间是否存在任何可辨别的差异(可能性能)str.indexOf("src")
和
str.match(/src/)
我个人更喜欢match
(和regexp),但同事似乎走了另一条道路。我们想知道它是否重要......?
编辑:
我应该在一开始就说过,这是为了进行部分普通字符串匹配的函数(在JQuery的类属性中选择标识符),而不是使用通配符等进行完整的正则表达式搜索。
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
所以它的区别在于:
string.indexOf('DisablesGuiClass-');
VS
string.match(/DisablesGuiClass-/)
答案 0 :(得分:53)
RegExp确实比indexOf慢(你可以看到它here),虽然通常这应该不是问题。使用RegExp,您还必须确保正确转义字符串,这是一个值得思考的额外内容。
除了这两个问题之外,如果两个工具完全符合您的需求,为什么不选择更简单的工具呢?
答案 1 :(得分:19)
您的比较可能不完全公平。 indexOf
与普通字符串一起使用,因此非常快; match
采用正则表达式 - 当然它可能比较慢,但是如果你想进行正则表达式匹配,你将无法与indexOf
相提并论。另一方面,正则表达式引擎可以进行优化,并且在过去几年中一直在提高性能。
在您的情况下,如果您要查找逐字字符串,indexOf
就足够了。但是仍然有一个正则表达式的应用程序:如果你需要匹配整个单词并希望避免匹配子字符串,那么正则表达式会给你“单词边界锚点”。例如:
indexOf('bar')
会在bar
中找到bar, fubar, barmy
三次,而
match(/\bbar\b/)
仅当bar
不属于较长的单词时才会匹配。
正如您在评论中所看到的,已经进行了一些比较,表明正则表达式可能比indexOf
更快 - 如果它的性能至关重要,您可能需要对代码进行概要分析。
答案 2 :(得分:8)
如果您尝试搜索子字符串出现不区分大小写,那么match
似乎比indexOf
和toLowerCase()
的组合更快
答案 3 :(得分:6)
您是否应该首选str.indexOf('target')
或str.match(/target/)
。正如其他海报所建议的那样,这些方法的用例和返回类型是不同的。第一个问“str
我在哪里可以找到'target'
?”第二个问“是str
匹配正则表达式,如果是,那么任何相关捕获组的所有匹配是什么?”
问题在于,在技术上没有一个设计用于提出更简单的问题“字符串是否包含子字符串?”有明确设计的东西:
var doesStringContainTarget = /target/.test(str);
使用regex.test(string)
有几个好处:
str.match(/target/)
(和竞争对手str.indexOf('target')
)str
为undefined
或null
,您将获得false
(所需结果),而不是投放TypeError
< / LI>
醇>
答案 4 :(得分:5)
理论上,当你只是搜索一些纯文本时,使用indexOf
应该比正则表达式更快,但如果你担心性能,你应该自己做一些比较基准测试。
如果您更喜欢match
并且它足够快以满足您的需求,那就去吧。
对于它的价值,我同意你的同事:我在搜索普通字符串时使用indexOf
,并且仅当我需要常规提供的额外功能时才使用match
等表达式。
答案 5 :(得分:4)
明智的表现indexOf
至少会比match
略快。这一切都归结为具体实施。在决定使用哪个问题时,请问自己以下问题:
整数索引是否足够或是我 需要RegExp的功能 匹配结果?
答案 6 :(得分:3)
除了其他答案所解决的性能影响之外,重要的是要注意每种方法的返回值是不同的;所以这些方法不能仅仅在不改变你的逻辑的情况下被替换。
.indexOf
的返回值:integer
第一次出现指定值的调用
String
对象中的索引,从fromIndex
开始搜索。
如果值为,则返回-1
找不到。
.match
的返回值:array
包含整个匹配结果和任何括号捕获的匹配结果的数组。
如果没有匹配,则返回null
。
如果.indexOf
返回0
,如果调用字符串以指定值开始,则简单的真理测试将失败。
例如:
鉴于此课程......
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'
...每个的返回值会有所不同:
// returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
… // this block is skipped.
}
VS
// returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) {
… // this block is run.
}
使用.indexOf
返回来运行真值测试的正确方法是针对-1
进行测试:
if (string.indexOf('DisablesGuiClass-') !== -1) {
// ^returns `0` ^evaluates to `true`
… // this block is run.
}
答案 7 :(得分:2)
有所有可能的方式来搜索字符串
// 1.包含(在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:测试
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);
基准似乎特别针对es6 includes扭曲,请阅读注释。
如果您不需要匹配项。 =>要么需要正则表达式,然后使用 test 。否则,es6 包括或 indexOf 。仍然测试与 indexOf 接近。
它们似乎是相同的:https://jsperf.com/array-indexof-vs-includes/4(如果不同,那会很奇怪,除了表现出check this的差异外,它们的性能基本相同)
并进行我自己的基准测试。这是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
简历:包含和indexOf具有相同的性能。测试较慢。
长文本(比普通文本长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包含 =>效果相同
测试 =>对于短字符串或文本,可能会变慢。与长文本相同。对于正则表达式引擎增加的开销,这是有意义的。在Chrome中,这似乎没有任何关系。
答案 8 :(得分:0)
只有在您真正需要时才会使用indexOf
来存在子串和match
。即如果您在一个也可能包含src
的字符串中搜索单词 altsrc
,那么aString.match(/\bsrc\b/)
确实更合适。
答案 9 :(得分:0)
请记住,Internet Explorer 8并不理解indexOf
。
但是,如果您的用户中没有人使用ie8(谷歌分析会告诉你),而不是省略这个答案。
修复ie8的可能解决方案:
How to fix Array indexOf() in JavaScript for Internet Explorer browsers