1. 程式人生 > >解讀replace的第二個引數為函式

解讀replace的第二個引數為函式

在js中,str.replace(RegExp,function(args){});第二個引數為函式,為了更好的解釋,我在這裡把函式裡的引數暫作為陣列args。
首先明確第一點:args的長度並不固定,它的長度是根據你所傳遞的正則表示式RegExp所定,具體是怎麼確定的後面介紹。
第二點:
我們先讓args具體化一下。args = [1,...,args.length,length-2,args.length-1];這裡面的數值在此代表著陣列的下標而不是內容。
雖然args的長度不確定,但有三個位置的值是可以確定的。這三個位置便是1,args.length,length-2,args.length-1。
也就是引數的第一項,和最後兩項,這三個位置分別對應:當前匹配的值,匹配項在字串中的最小位置,原始字串。
第三點:
既然有三個位置的值可以確定,那麼除此三個引數外,中間的引數是什麼?
中間的引數對應著正則表示式中子表示式捕獲組的值。如果子表示式匹配成功則將捕獲組的值放到中間的引數中,如果沒有匹配成功,
那麼會用undefined來佔位。

來看一個例子:
var str = '<li><a <%=src%>></a><li><a <%=src%>></a>';
var reg =  /<%-([\s\S]+?)%>|<%=([\s\S]+?)%>|<%([\s\S]+?)%>|$/g;
str.replace(reg,function(a,b,c,d,e,f){
    console.log(a,b,c,d,e,f);
});

分析:
    函式中的引數應該有幾位?
    首先可以確定有三個引數是肯定存在的,然後整個正則表示式有三個子表示式,那麼又有三個引數加入進來,之後分析子表示式。每個子表示式各有一個捕獲組,所以不需要額外新增引數位置,如果捕獲組的個數超出1,則需要新增引數的個數。最後相加3+3為6.引數一共有6位。

    我們只看一次的匹配後輸出的結果  :

 <%=src%> undefined src undefined 7 <li><a <%=src%>></a><li><a <%=src%>></a>

第一個undefined代表第一個子表示沒有匹配成功,第三個undefined代表第三個子表示沒有匹配成功。