在前端開發中,正則表達式是一大利器。所以我們這次就來討論下match()方法。
match本身是JavaScript語言中字符串對象的一個方法,該方法的簽名是
match([string] | [RegExp])
它的參數既可以是一個字符串,也可以是一個正則表達式。該方法絕大多數都是要使用正則表達式的,所以參數為string的情況不在本文討論范圍之內。其實參數即使是一個簡單的string,其返回值也跟使用正則表達式的結果無異,而且使用正則表達式的變化比較多,用法復雜,所以我們只討論正則的用法。
一、返回值問題。
我們必須明確的是,這個方法跟其他語言是不同的。JavaScript中的match()方法的返回值是數組或者是null。如果原字符串中匹配到了正則表達式指代的子串,則返回一個數組,否則返回null。
二、不使用全局匹配
var str = 'Today is the 186th day of 2018,I must finish these 2 projects within 21 days.'; var results = str.match(/\d+/); //只能匹配字符串中出現的首個數字,未使用全局匹配符g console.log(results);
輸出的結果是:
再強調一次,這個例子的結果是沒有使用全局匹配的正則表達式的匹配結果。說白了,就是正則表達式的末尾沒跟g。由於不適用全局匹配,所以match()方法只找到源字符串中首次匹配的子串后,就立刻得到返回結果,不再比較之后剩余的部分是否還有能匹配上的內容。
我們可以看到,match()的結果是一個數組,該數組一共有4項。各項代表的意思如下:
第0項:匹配到字符串
第1項:groups:undefined,這表示當前的正則表達式沒使用分組
第2項:index表示首次匹配上的子串的起始下標。
第3項:input,表示源字符串
第4項:length,表示匹配到的結果個數,由於這里不使用全局匹配,只找到首次匹配項就結束了,所以匹配結果只有1個,length也就是1。
再次強調下,如果在正則表達式末尾不使用全局匹配符g,在本例中是無法匹配到所有的數字。反過來說就是,如果想匹配所有的符合條件的子串,就必須在正則的末尾添加全局匹配符g
三、使用全局匹配
var str = 'Today is the 186th day of 2018,I must finish these 2 projects within 21 days.'; var results = str.match(/\d+/g); //匹配所有的數字,使用了全局匹配符g console.log(results);
這次我們在正則表達式的末尾添加了 g,該正則表達式的意圖是,在字符串str中匹配出所有的由數字組成的子符串。
這次結果如下:
可以看到,這次的返回值仍然是個數組,只不過這個數組的內容跟上邊不使用全局匹配時大不相同的。由於原字符串中出現了4個數字組成的子串的情況,所以該數組中出現了4個項。length屬性同樣為匹配到的結果個數,這里顯然是4個。
仔細看會發現,此時返回的數組中,沒有index,input這2項,不過這兩項並不十分重要。
四、使用分組
使用分組時的情況比較麻煩,還要看有沒有使用全局匹配,也就是有沒有在正則表達式的末尾添加g
4.1 使用分組,且不使用g
var str = 'Today is the 286th day of 2018, the 108th Thanksgiving Day.'; var results = str.match(/\d+(th)/); //匹配str中首個以數字開頭,並且以th結尾的子串 console.log(results);
輸出結果是:
由於該正則表達式為: /\d (th) /,該表達式中使用了小括號(),在此處的作用為分組。所以match()的結果是帶有分組特征的。返回的數組包含多個元素,第一個元素是以貪婪模式找到的最長的匹配,之后的元素依次為該匹配中的第一、第二、第三 ......個分組,這里只有1個分組,所以也就只匹配到1個分組結果,也就是”th"。
假如正則表達式改成:/\d+(t)(h)/,那么匹配到的項就有3個,分別是 : '286th' 、 't' 、'h'。我相信大家看到這里,對於分組的意義,以及如何匹配分組就已經了解了。
數組中其它項不在解釋了,參考上邊的。
需要注意的是,這種結果是前提是:1.使用分組,2.不做全局匹配。
4.2 使用分組,同時使用全局匹配g
var str = 'Today is the 286th day of 2018, the 108th Thanksgiving Day.'; var results = str.match(/\d+(th)/g); //匹配str中所有的以數字開頭,並且以th結尾的子串 console.log(results);
這次的代碼,跟上次的代碼區別只有一點,就是正則表達式末尾多了個g,表示全局匹配。
結果也是大不相同的。
結果說明了一切,當正則中使用全局匹配符g,即使有分組的存在,在匹配結果中也只有匹配到的最長的,那些分組的子匹配都不見了。
具體表現為:這次匹配到的結果是 ’286th‘ 和 ‘’108th’ ,前一個例子中使用分組是出線的那個單獨的分組子匹配 ‘th’,這一項不見了。我們把這個現象理解為,只要使用了全局匹配模式,那么match()將只返回“貪婪”的匹配結果,這里的“貪婪”指的就是只招那個最長的能匹配上的字符串,至於分組項,就忽略了。