字符串搜索匹配之 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方法的搜索條件時,是區分大小寫的。

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