JavaScript:搜索字符串时的 indexOf 与匹配?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4757438/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JavaScript: indexOf vs. Match when Searching Strings?
提问by indra
Readability aside, are there any discernable differences (performance perhaps) between using
除了可读性之外,使用之间是否有任何可辨别的差异(可能是性能)
str.indexOf("src")
and
和
str.match(/src/)
I personally prefer match
(and regexp) but colleagues seem to go the other way. We were wondering if it mattered ...?
我个人更喜欢match
(和正则表达式),但同事们似乎反其道而行之。我们想知道这是否重要......?
EDIT:
编辑:
I should have said at the outset that this is for functions that will be doing partial plain-string matching (to pick up identifiers in class attributes for JQuery) rather than full regexp searches with wildcards etc.
我应该在一开始就说过,这是针对将进行部分纯字符串匹配(以在 JQuery 的类属性中获取标识符)而不是使用通配符等进行完整正则表达式搜索的函数。
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
So its the difference between:
所以它的区别在于:
string.indexOf('DisablesGuiClass-');
VS
VS
string.match(/DisablesGuiClass-/)
采纳答案by David Tang
RegExp is indeed slower than indexOf (you can see it here), though normally this shouldn't be an issue. With RegExp, you also have to make sure the string is properly escaped, which is an extra thing to think about.
RegExp 确实比 indexOf 慢(你可以在这里看到它),但通常这不应该是一个问题。使用 RegExp,您还必须确保正确转义字符串,这是需要考虑的额外事项。
Both of those issues aside, if two tools do exactly what you need them to, why not choose the simpler one?
撇开这两个问题不谈,如果两个工具完全满足您的需求,为什么不选择更简单的一个呢?
回答by Tim Pietzcker
Your comparison may not be entirely fair. indexOf
is used with plain strings and is therefore very fast; match
takes a regular expression - of course it may be slower in comparison, but if you want to do a regex match, you won't get far with indexOf
. On the other hand, regular expression engines can be optimized, and have been improving in performance in the last years.
您的比较可能并不完全公平。indexOf
与普通字符串一起使用,因此速度非常快;match
采用正则表达式 - 当然相比之下它可能会更慢,但是如果你想做一个正则表达式匹配,你不会用indexOf
. 另一方面,正则表达式引擎可以优化,并且在过去几年中一直在提高性能。
In your case, where you're looking for a verbatim string, indexOf
should be sufficient. There is still one application for regexes, though: If you need to match entirewords and want to avoid matching substrings, then regular expressions give you "word boundary anchors". For example:
在您的情况下,您正在寻找逐字字符串,indexOf
应该就足够了。不过,正则表达式仍然有一个应用程序:如果您需要匹配整个单词并希望避免匹配子字符串,那么正则表达式将为您提供“单词边界锚点”。例如:
indexOf('bar')
will find bar
three times in bar, fubar, barmy
, whereas
将在 中找到bar
3 次bar, fubar, barmy
,而
match(/\bbar\b/)
will only match bar
when it is not part of a longer word.
只有bar
当它不是较长单词的一部分时才会匹配。
As you can see in the comments, some comparisons have been done that show that a regex may be faster than indexOf
- if it's performance-critical, you may need to profile your code.
正如您在评论中所看到的,已经进行了一些比较,表明正则表达式可能比indexOf
- 如果它对性能至关重要,您可能需要分析您的代码。
回答by Yogesh Mangaj
If you're trying to search for substring occurrences case-insensitivelythen match
seems to be faster than a combination of indexOf
and toLowerCase()
如果你想搜索的子串出现不区分大小写然后match
似乎是比快的组合indexOf
和toLowerCase()
Check here - http://jsperf.com/regexp-vs-indexof/152
回答by Mohamed Allal
Here all possible ways (relatively) to search for string
这里所有可能的方式(相对)搜索字符串
// 1. includes (introduced in ES6)
// 1. 包含(在 ES6 中引入)
var string = "string to search for substring",
substring = "sea";
string.includes(substring);
// 2. string.indexOf
// 2. string.indexOf
var string = "string to search for substring",
substring = "sea";
string.indexOf(substring) !== -1;
// 3. RegExp: test
// 3. 正则表达式:测试
var string = "string to search for substring",
expr = /sea/; // no quotes here
expr.test(string);
// 4. string.match
// 4. 字符串匹配
var string = "string to search for substring",
expr = "/sea/";
string.match(expr);
//5. string.search
//5. 字符串搜索
var string = "string to search for substring",
expr = "/sea/";
string.search(expr);
Here a src: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
这里有一个 src:https: //koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31
Benchmarks seem to be twisted specially for es6 includes , read the comments.
基准似乎是专门为 es6 includes 扭曲的,请阅读评论。
In resume:
在简历中:
if you don't need the matches. => Either you need regex and so use test. Otherwise es6 includesor indexOf. Still testvs indexOfare close.
如果你不需要火柴。=> 要么你需要正则表达式,所以使用test。否则 es6包含或indexOf。仍然测试与indexOf接近。
And for includes vs indexOf:
对于包含与 indexOf:
They seem to be the same : https://jsperf.com/array-indexof-vs-includes/4(if it was different it would be wierd, they mostly perform the same except for the differences that they expose check this)
它们似乎是相同的:https: //jsperf.com/array-indexof-vs-includes/4(如果不同,那就很奇怪了,除了它们公开的差异之外,它们的性能大多相同,请检查此内容)
And for my own benchmark test. here it is http://jsben.ch/fFnA0You can test it (it's browser dependent) [test multiple time] here how it performed (multiple run indexOf and includes one beat the other, and they are close). So they are the same. [here using the same test platform as the article above].
对于我自己的基准测试。这里是http://jsben.ch/fFnA0你可以测试它(它依赖于浏览器)[多次测试]这里它是如何执行的(多次运行 indexOf 并且包括一个击败另一个,它们很接近)。所以他们是一样的。[此处使用与上述文章相同的测试平台]。
And here for the a long text version (8 times longer) http://jsben.ch/wSBA2
这里是长文本版本(长 8 倍) http://jsben.ch/wSBA2
Tested both chrome and firefox, same thing.
测试了chrome和firefox,同样的事情。
Notice jsben.ch doesn't handle memory overflow (or there limits correctly. It doesn't show any message) so result can get wrong if you add more then 8 text duplication (8 work well). But the conclusion is for very big text all three perform the same way. Otherwise for short indexOf and includes are the same and test a little bit slower. or Can be the same as it seemed in chrome (firefox 60 it is slower).
请注意 jsben.ch 不处理内存溢出(或正确限制。它不显示任何消息),因此如果添加超过 8 个文本重复(8 个工作良好),结果可能会出错。但结论是对于非常大的文本,所有三个都以相同的方式执行。否则对于简短的 indexOf 和包含是相同的,并且测试速度会慢一点。或 可以与在 chrome 中看起来相同(firefox 60 更慢)。
Notice with jsben.ch: don't freak out if you get inconsistant result. Try different time and see if it's consistent or not. Change browser, sometimes they just run totally wrong. Bug or bad handling of memory. Or something.
请注意 jsben.ch:如果您得到不一致的结果,请不要惊慌。尝试不同的时间,看看它是否一致。更换浏览器,有时他们只是运行完全错误。错误或内存处理不当。或者其他的东西。
ex:
前任:
Here too my benchmark on jsperf (better details, and handle graphs for multiple browsers)
这里也是我对 jsperf 的基准测试(更好的细节,并处理多个浏览器的图形)
(top is chrome)
(顶部是镀铬)
normal texthttps://jsperf.com/indexof-vs-includes-vs-test-2019
resume:includes and indexOf have same perofrmance. test slower.
普通文本https://jsperf.com/indexof-vs-includes-vs-test-2019
简历:includes 和 indexOf 具有相同的性能。测试比较慢。
(seem all three perform the same in chrom)
Long text(12 time longer then normal)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume:All the three perform the same. (chrome and firefox)
长文本(比普通文本长12 倍)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume:三者的表现相同。(铬和火狐)
very short stringhttps://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume:includes and indexOf perform the same and test slower.
非常短的字符串https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume:includes 和 indexOf 执行相同但测试速度较慢。
Note: about the benchmark above. For the very short stringversion (jsperf) had an big error for chrome. Seeing by my eyes. around 60 sample was run for both indexOf and includes same way (repeated a lot of time). And test a little bit less and so slower. don't be fooled with the wrong graph. It's clear wrong. Same test work ok for firefox, surely it's a bug.
注意:关于上面的基准。对于非常短的字符串版本(jsperf),chrome 有一个很大的错误。亲眼所见。为 indexOf 运行了大约 60 个样本,并包括相同的方式(重复了很多时间)。并测试少一点,所以更慢。不要被错误的图表所迷惑。很明显错了。Firefox 的测试工作正常,当然这是一个错误。
Here the illustration: (the first image was the test on firefox)
waaaa. Suddenly indexOf became superman. But as i said i did the test, and looked at the number of samples it was around 60. Both indexOf and includes and they performed the same. A bug on jspref. Except for this one (maybe because of a memory restriction related problem) all the rest was consistent, it give more details. And you see how many simple happen in real time.
这是插图:(第一张图片是在 Firefox 上的测试)
waaaa。突然 indexOf 变成了超人。但正如我所说,我做了测试,并查看了大约 60 个样本的数量。 indexOf 和包括它们的表现都是一样的。jspref上的一个错误。除了这个(可能是因为内存限制相关的问题),其余的都是一致的,它提供了更多的细节。你会看到有多少简单的事情实时发生。
Final resume
最终简历
indexOf vs includes=> Same performance
indexOf 与包含=> 相同的性能
test=> can be slower for short strings or text. And the same for long texts. And it make sense for the overhead that the regex engine add. In chrome it seemed it doesn't matter at all.
test=> 对于短字符串或文本可能会更慢。对于长文本也是如此。这对于正则表达式引擎添加的开销是有意义的。在 chrome 中,它似乎根本无关紧要。
回答by elreimundo
You ask whether str.indexOf('target')
or str.match(/target/)
should be preferred. As other posters have suggested, the use cases and return types of these methods are different. The first asks "where in str
can I first find 'target'
?" The second asks "does str
match the regex and, if so, what are all of the matches for any associated capture groups?"
你问是否str.indexOf('target')
或str.match(/target/)
应该优先考虑。正如其他海报所建议的那样,这些方法的用例和返回类型是不同的。第一个问“str
我在哪里可以先找到'target'
?” 第二个询问“是否str
匹配正则表达式,如果匹配,任何相关捕获组的所有匹配项是什么?”
The issue is that neither one technically is designed to ask the simpler question "does the string contain the substring?" There is something that is explicitly designed to do so:
问题在于,从技术上讲,没有一个人旨在提出更简单的问题“字符串是否包含子字符串?” 有一些东西是明确设计的:
var doesStringContainTarget = /target/.test(str);
There are several advantages to using regex.test(string)
:
使用 有几个优点regex.test(string)
:
- It returns a boolean, which is what you care about
- It is more performant than
str.match(/target/)
(and rivalsstr.indexOf('target')
) - If for some reason,
str
isundefined
ornull
, you'll getfalse
(the desired result) instead of throwing aTypeError
- 它返回一个布尔值,这是你关心的
- 它比
str.match(/target/)
(和竞争对手str.indexOf('target')
)性能更高 - 如果由于某种原因
str
是undefined
或null
,您将获得false
(所需的结果)而不是抛出TypeError
回答by LukeH
Using indexOf
should, in theory, be faster than a regex when you're just searching for some plain text, but you should do some comparative benchmarks yourself if you're concerned about performance.
indexOf
理论上,当您只是搜索一些纯文本时,使用应该比正则表达式更快,但是如果您担心性能,您应该自己进行一些比较基准测试。
If you prefer match
and it's fast enough for your needs then go for it.
如果您愿意,match
并且它的速度足以满足您的需求,那就去吧。
For what it's worth, I agree with your colleagues on this: I'd use indexOf
when searching for a plain string, and use match
etc only when I need the extra functionality provided by regular expressions.
就其价值而言,我同意您的同事的看法:我会indexOf
在搜索纯字符串时使用,match
仅在需要正则表达式提供的额外功能时才使用etc。
回答by ChaosPandion
Performance wise indexOf
will at the very least be slightly faster than match
. It all comes down to the specific implementation. When deciding which to use ask yourself the following question:
性能方面indexOf
至少会比match
. 这一切都归结为具体的实现。在决定使用哪个时,问自己以下问题:
Will an integer index suffice or do I need the functionality of a RegExp match result?
整数索引是否足够,或者我是否需要 RegExp 匹配结果的功能?
回答by gfullam
The return values are different
返回值不同
Aside from the performance implications, which are addressed by other answers, it is important to note that the return values for each method are different; so the methods cannot merely be substituted without also changing your logic.
除了其他答案解决的性能影响之外,重要的是要注意每种方法的返回值是不同的;所以这些方法不能仅仅被替换而不改变你的逻辑。
Return value of .indexOf
: integer
的返回值.indexOf
:integer
The index within the calling
String
object of the first occurrence of the specified value, starting the search atfromIndex
.
Returns-1
if the value is not found.
String
指定值第一次出现的调用对象内的索引,从 开始搜索fromIndex
。如果未找到该值,则
返回-1
。
Return value of .match
: array
的返回值.match
:array
An Array containing the entire match result and any parentheses-captured matched results.
Returnsnull
if there were no matches.
包含整个匹配结果和任何括号捕获的匹配结果的数组。如果没有匹配项,则
返回null
。
Because .indexOf
returns 0
if the calling string beginswith the specified value, a simple truthy test will fail.
因为如果调用字符串以指定值开头则.indexOf
返回,所以简单的真实测试将失败。0
For example:
例如:
Given this class…
鉴于这门课…
class='DisablesGuiClass-2345-2d73-83hf-8293 redBorder'
…the return values for each would differ:
...每个的返回值会有所不同:
// 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.
}
The correct way to run a truthy test with the return from .indexOf
is to test against -1
:
运行带有返回值的真实测试的正确方法.indexOf
是针对 进行测试-1
:
if (string.indexOf('DisablesGuiClass-') !== -1) {
// ^returns `0` ^evaluates to `true`
… // this block is run.
}
回答by NoWomenNoCry
remember Internet Explorer 8 doesnt understand indexOf
.
But if nobody of your users uses ie8 (google analytics would tell you) than omit this answer.
possible solution to fix ie8:
How to fix Array indexOf() in JavaScript for Internet Explorer browsers
记得 Internet Explorer 8 不明白indexOf
。但是,如果您的用户中没有人使用 ie8(谷歌分析会告诉您),请忽略此答案。修复 ie8 的可能解决方案:
How to fix Array indexOf() in JavaScript for Internet Explorer Browser