字符串搜索匹配之 test&search&indexOf&match&&exec&includes

这里要讨论的是字符串搜索匹配时常用到的API: test search indexOf match exec includes

  1. str.search(reg/str)
    该方法返回的是第一次匹配得到的结果,如果匹配到,返回第一次匹配得到的位置。如果没有匹配到,返回-1。
var a = 'foofoo'
var regexp1 = /foo/
var regexp2 = /foo/g
var s1 = a.search(regexp1)  //返回0
var s1 = a.search(regexp1) //依然返回0 ,因此每次都是从头开始匹配
var s2  = a.search(regexp2) //依然返回0, 因此正则表达式无论是否有全局标志都是只返回第一次匹配的位置,且每次都从头开始搜索
var s3 = a.search('foo') //返回0, 这里先将'foo'字符串通过new RegExp()构造出正则对象,然后再进行search操作

以上代码中s3的获取相当于进行了以下步骤:

var regexp3 = new RegExp('foo') //regexp3的值为:/foo/
var s3 = a.search(regexp3)

因此:对于search方法来说,每次都从字符串的第0位开始搜索并返回第一次匹配得到的位置,如果存在,则返回该位置,如果不存在,则返回-1。搜索条件可以是正则表达式也可以是字符串,如果是字符串的话每次都是先用new RegExp()隐式的转化成正则表达式,然后再进行匹配。

  1. reg.test(str)
    该方法的搜索条件必须是正则表达式,如果存在,则返回true,如果不存在,则返回false。如果正则表达式是全局搜索的(有/g),每次匹配结束后lastIndex的值都会发生变化,最开始是0,一次匹配完成后就变成下一轮匹配的起始地址。
var s4 = regexp1.test(a) // 返回true
var s4 = regexp1.test(a) // 依然返回true, 因为regexp1没有设置是全局搜索的
var s5 = regexp2.test(a) //返回true, 第一次匹配到结果,lastIndex变成3
var s5 = regexp2.test(a) //返回true,第二次匹配得到结果,lastIndex变成6
var s5 = regexp2.test(a)//返回false, 因为第三次匹配是从index=6开始匹配的,因此已经匹配不到了

因此:对于test方法来说,搜索条件只能是正则表达式,返回的结果只可能是true或者false, 如果是全局匹配,那么每次匹配完成后,lastIndex都会变成下次匹配的起始位置。因此在使用test方法时,不熟悉的使用者可能会觉得明明存在匹配结果,但还是返回false,就是因为设置了全局匹配,且已经进行了不止一次匹配。

  1. str.indexOf(searchValue[, fromIndex])
    该方法的搜索条件必须是字符串,如果匹配到结果,返回第一次匹配的位置,如果没有匹配到结果,则返回-1。且indexOf方法是可以设置从什么位置开始搜索的:str.indexOf(searchValue[, fromIndex]),默认从0开始搜索。
var s6 = a.indexOf('foo')//返回的是0
var s7 = a.indexOf('foo', 6)//因为6>=a.length, 所以返回的是-1
var s8 = a.indexOf('foo', -1) //因为-1<0, 所以返回的是0

如果搜索条件是空字符串,那么:

var s8 = a.indexOf('', -1) //因为搜索条件是空字符串且-1<0,所以返回0
var s9 = a.indexOf('', 2) //因为搜索条件是空字符串且0<=2<=a.length, 所以返回的即是该formIndex
var s10 = a.indexOf('', 7)//因为搜索条件是空字符串且7>a.length, 所以返回的即是a.length
  1. str.match(reg)
    如果传入的参数reg不是一个正则表达式对象,而是字符串,那么这里会和search函数一样通过new RegExp(str)将其隐式转换成正则表达式。
var  str = '#home#home'
var reg1 = 'home'
var match1 = str.match(reg1)

与下面代码得到的match2结果一样:

var  str = '#home#home'
var reg2 = /home/
var match2 = str.match(reg2)

在这里插入图片描述
注意这里的正则表达式并不包含全局标志g,如果包含的话,得到的结果为:

var  str = '#home#home'
var reg3 = /home/g
var match3 = str.match(reg3)

在这里插入图片描述
所以说,如果想要知道一个元素在字符串中出现的次数,可以用match全局匹配,得到数组的长度就是出现的次数。
以上3例都是匹配成功的例子,如果匹配不成功,则返回null

var  str = '#home#home'
var reg4 = /home1/g
var match4 = str.match(reg4)  //match4的结果为null

如果匹配规则为空,即没有给match方法传入参数,或者传入空字符串(’’)则返回结果为第一项为空字符串的数组

var  str = '#home#home'
var match4 = str.match() 

结果为:
在这里插入图片描述
如果正则表达式中包含捕获组,且没有全局匹配标志g,那么:

var  str = '#home#home'
var reg5 = /(#)home/
var match5 = str.match(reg5) 

得到的数组第二个元素是捕获组捕获到的结果:
在这里插入图片描述
如果包含捕获组,但是同时也设置了全局标志,那么捕获组会被忽略

var  str = '#home#home'
var reg6 = /(#)home/g
var match6 = str.match(reg6)

得到的结果为:
在这里插入图片描述
总结:使用match方法主要一是可以使用全局标志g来获取一个元素在str中出现的次数,二是可以通过捕获组来获取子匹配(不能有全局标志g),其他的功能search方法也可以实现。

  1. reg.exec(str)
    reg必须是正则对象,无论正则表达式中是否有全局标志g,均可以获得和match方法不带全局标志g一样的结果,都是返回第一次匹配的结果。
var  str = '#home#home'
var reg1 = /(#)home/
var reg2 = /(#)home/g
var match1 = reg1.exec(str)
var match2 = reg2.exec(str)

得到的结果均为:
在这里插入图片描述
这里要注意的一点是,正则表达式带和不带全局标志g在匹配时的不同点在于:带全局标志g每次匹配后,匹配位置(lastIndex)变成下次匹配的起始位置。
如果没有匹配到结果,跟match方法一样,返回null

var  str = '#home#home'
var reg3 = /(#)home1/
var match3 = reg3.exec(str)  //match3结果为null

总结:使用exec方法要注意的是如果设置了全局标志g,则每次的匹配位置lastIndex会改变。

  1. str.includes(substr)
    如果substr是str的子串,则返回true,否则返回false。这里substr只能是字符串,不能是正则表达式。
var a = 'foofoo'
a.includes('f') //true
a.includes('foo') //true
a.includes('foofoo') //true

a.includes('') //true

因此如果substr是空字符串的话,返回true。
注意:当字符串作为search/indexOf/match/includes方法的搜索条件时,是区分大小写的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章