JavaScript:搜索字符串时indexOf与Match?

JavaScript:搜索字符串时indexOf与Match?,javascript,regex,string,client,Javascript,Regex,String,Client,撇开可读性不谈,使用 str.indexOf("src") 及 我个人更喜欢match(和regexp),但同事们似乎相反。我们想知道这是否重要 编辑: 我应该在一开始就说,这是针对将进行部分纯字符串匹配(为JQuery提取类属性中的标识符)的函数,而不是使用通配符等进行完整的regexp搜索 class='redBorder DisablesGuiClass-2345-2d73-83hf-8293' 因此,这是以下两者之间的区别: string.indexOf('D

撇开可读性不谈,使用

str.indexOf("src") 

我个人更喜欢
match
(和regexp),但同事们似乎相反。我们想知道这是否重要

编辑:

我应该在一开始就说,这是针对将进行部分纯字符串匹配(为JQuery提取类属性中的标识符)的函数,而不是使用通配符等进行完整的regexp搜索

class='redBorder DisablesGuiClass-2345-2d73-83hf-8293' 
因此,这是以下两者之间的区别:

string.indexOf('DisablesGuiClass-');


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

如果你喜欢
匹配
,而且速度足够快,满足你的需要,那么就去吧


值得一提的是,我同意你的同事们的看法:我在搜索普通字符串时会使用
indexOf
,只有在我需要正则表达式提供的额外功能时才使用
match
等。

性能方面的
indexOf
至少会比
match
稍快一些。这一切都归结于具体的实现。在决定使用哪种方法时,问自己以下问题:

一个整数索引是否足够 需要RegExp的功能吗 比赛结果


你的比较可能不完全公平
indexOf
与普通字符串一起使用,因此速度非常快
match
采用正则表达式-当然,相比之下它可能会慢一些,但是如果您想进行正则表达式匹配,那么使用
indexOf
就走不了多远。另一方面,正则表达式引擎可以优化,并且在过去几年中性能一直在提高

在您的情况下,如果要查找逐字字符串,
indexOf
应该足够了。不过,正则表达式还有一个应用程序:如果您需要匹配整个单词,并且希望避免匹配子字符串,那么正则表达式将为您提供“单词边界锚”。例如:

indexOf('bar')
将在
bar、fubar、barmy
中找到
bar
三次,而

match(/\bbar\b/)
只有当它不是较长单词的一部分时,才会匹配
bar


正如您在评论中所看到的,已经做了一些比较,表明正则表达式可能比indexOf快-如果它是性能关键的,您可能需要分析您的代码。

RegExp确实比indexOf慢(您可以看到),尽管通常这不应该是一个问题。使用RegExp时,您还必须确保字符串被正确转义,这是一件额外需要考虑的事情


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

如果您试图不区分大小写地搜索子字符串的出现情况,那么
匹配
似乎比
indexOf
toLowerCase()

选中此处-

返回值不同 除了通过其他答案解决的性能影响之外,重要的是要注意每个方法的返回值是不同的;因此,在不改变逻辑的情况下,这些方法不能仅仅被替代

的返回值:
整数

指定值第一次出现的调用
字符串
对象中的索引,在
fromIndex开始搜索
如果未找到该值,则返回
-1

返回:
数组的值

包含整个匹配结果和捕获的匹配结果的任何括号的数组。
如果没有匹配项,则返回
null

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

例如:

考虑到这门课

…每个的返回值将不同:

vs

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

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

您询问是否应首选
str.indexOf('target')
str.match(/target/)
。正如其他海报所建议的,这些方法的用例和返回类型是不同的。第一个问题是“在
str
中,我可以首先在哪里找到
'target'
?”第二个问题是“str
是否与正则表达式匹配,如果匹配,任何相关捕获组的所有匹配项是什么?”

问题在于,从技术上讲,这两个问题都不是设计用来问更简单的问题“字符串是否包含子字符串?”有一个明确设计用来这样做的问题:

var doesStringContainTarget = /target/.test(str);
使用
regex.test(string)
有几个优点:

  • 它返回一个布尔值,这正是您所关心的
  • 它比
    str.match(/target/)
    (和竞争对手
    str.indexOf('target')
  • 如果由于某种原因,
    str
    未定义的
    空的
    ,您将得到
    false
    (所需结果),而不是抛出
    类型错误

  • 请记住,Internet Explorer 8不理解
    indexOf
    。 但如果你的用户中没有人使用ie8(谷歌分析会告诉你),那就省略这个答案。 修复ie8的可能解决方案:

    这里有所有可能的方法(相对地)来搜索字符串

    //一,。包括(在ES6中引入)

    //二,。string.indexOf

    var string = "string to search for substring",
        substring = "sea";
    string.indexOf(substring) !== -1;
    
    //三,。RegExp:test

    var string = "string to search for substring",
        expr = /sea/;  // no quotes here
    expr.test(string);
    
    //四,。字符串匹配

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

    var string = "string to search for substring",
        expr = "/sea/";
    string.search(expr);
    
    这里是src:

    阅读评论,基准测试似乎是专门针对es6的

    在简历中: 如果你不需要火柴。 =>您需要正则表达式,因此使用测试。否则,es6包括
    var doesStringContainTarget = /target/.test(str);
    
    var string = "string to search for substring",
        substring = "sea";
    string.includes(substring);
    
    var string = "string to search for substring",
        substring = "sea";
    string.indexOf(substring) !== -1;
    
    var string = "string to search for substring",
        expr = /sea/;  // no quotes here
    expr.test(string);
    
    var string = "string to search for substring",
        expr = "/sea/";
    string.match(expr);
    
    var string = "string to search for substring",
        expr = "/sea/";
    string.search(expr);