JavaScript:indexOf与searchstring时匹配?
抛开可读性,使用之间是否存在可辨别的差异(性能可能)
str.indexOf("src")
和
str.match(/src/)
我个人更喜欢match
(和正则expression式),但同事似乎走向另一条路。 我们想知道它是否重要…?
编辑:
我应该从一开始就表示,这是为了执行部分简单string匹配(在JQuery的类属性中select标识符)的函数,而不是使用通配符进行完整的正则expression式search等。
class='redBorder DisablesGuiClass-2345-2d73-83hf-8293'
所以它的区别在于:
string.indexOf('DisablesGuiClass-');
VS
string.match(/DisablesGuiClass-/)
RegExp确实比indexOf慢(你可以在这里看到),但通常这不应该是一个问题。 使用RegExp,您还必须确保string正确转义,这是一个额外的事情要考虑。
除了这两个问题之外,如果两个工具完全符合你的需求,为什么不select更简单的工具呢?
你的比较可能不完全公平。 indexOf
使用简单的string,因此速度非常快; match
需要一个正则expression式 – 当然,它可能会比较慢,但是如果你想做一个正则expression式匹配,你不会得到indexOf
。 另一方面,正则expression式引擎可以被优化,并且在过去的几年中一直在提高性能。
在你的情况,你在寻找一个逐字string, indexOf
应该是足够的。 然而,仍然有一个正则expression式的应用程序:如果你需要匹配整个单词,并希望避免匹配的子string,则正则expression式给你“单词边界锚”。 例如:
indexOf('bar')
会在bar, fubar, barmy
findbar
三次,而
match(/\bbar\b/)
只有当它不是一个长词的一部分时才会匹配。
正如你在评论中看到的那样,已经做了一些比较,表明正则expression式可能比indexOf
更快 – 如果它对性能至关重要,那么可能需要对代码进行概要分析。
如果您试图以大小写不敏感的方式search子string,则match
似乎比indexOf
和toLowerCase()
的组合更快
使用indexOf
在理论上应该比正则expression式快一些,但是如果你关心性能,你应该自己做一些比较基准testing。
如果你喜欢match
,而且速度足够满足你的需求,那就去做吧。
对于它的价值,我同意你的同事:我会使用indexOf
search一个纯string,并使用match
等只有当我需要正则expression式提供的额外function。
你问str.indexOf('target')
还是str.match(/target/)
应该是首选的。 正如其他海报所build议的,这些方法的用例和返回types是不同的。 第一个问“我能在哪里find'target'
?” 第二个问题是“ str
匹配正则expression式,如果是,那么所有相关捕获组的匹配是什么?”
问题是没有一个技术上被devise成问一个更简单的问题:“string是否包含子string? 有一些明确的devise是这样做的:
var doesStringContainTarget = /target/.test(str);
使用regex.test(string)
有几个好处:
- 它返回一个布尔值,这是你所关心的
- 它比
str.match(/target/)
更str.match(/target/)
和str.indexOf('target')
) - 如果由于某种原因,
str
是undefined
或为null
,那么您将得到false
(所需的结果)而不是抛出TypeError
性能明智的indexOf
将至less比match
略快。 这一切都归结为具体的实施。 在决定使用哪一个时,问问自己以下问题:
整数索引是否足够了,还是需要RegExp匹配结果的function?
返回值是不同的
除了其他答案所涉及的性能影响外,重要的是要注意每种方法的返回值是不同的; 所以这些方法不能在不改变你的逻辑的情况下被取代。
.indexOf
: integer
返回值
第一次出现指定值的调用
String
对象内的索引,从fromIndex
处开始search。
如果未find该值,则返回-1
。
.match
: array
返回值
包含完整匹配结果和任何括号的数组捕获的匹配结果。
如果没有匹配,则返回null
。
因为如果调用string以指定值开始 ,则.indexOf
返回0
则简单的真实性testing将失败。
例如:
鉴于这个class…
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返回的truthytesting的正确方法是对-1
进行testing:
if (string.indexOf('DisablesGuiClass-') !== -1) { // ^returns `0` ^evaluates to `true` … // this block is run. }
总是使用indexOf
来存在子string,并且只有在实际需要时才match
。 也就是说,如果你正在一个string中searchsrc
,那么也可能包含altsrc
那么aString.match(/\bsrc\b/)
确实更合适。
记得Internet Explorer 8不理解indexOf
。 但是,如果你的用户没有人使用ie8(谷歌分析会告诉你)比省略这个答案。 可能的解决scheme,以解决ie8: 如何修复在JavaScript的Internet Explorer浏览器的Array indexOf()