正則表達式作為一種匹配處理字符串的利器在很多語言中都得到了廣泛實現和應用,web開發本質上是處理字符串(服務端接受請求處理后拼接字符串作為響應,這在早期的CGI編程中最明顯,然后客戶端解析字符串進行渲染和執行),所以說,JS作為一門常用於web開發的語言,必然要具備正則這種強大的特性,本文將對JS中的正則用法及常用函數進行一番總結。
1.正則對象及其屬性
首先正則對象是JS中內置的一個對象,好比Array以及Math一樣,不需要第三方庫的支持,通常我們采取兩種方式來定義一個正則對象
1)構造函數方式
var reg=new RegExp('abc','gi');
這里,第一個參數是正則的內容,第二個參數是修飾符,修飾符通常有三種,i,g,m,i表示的含義是忽略大小寫進行匹配,g表示全局匹配即匹配到第一個之后不停止繼續匹配,m表示多行匹配即遇到換行后不停止匹配繼續直到被匹配字符串結束。
2)字面量方式
var reg=/abc/gi;
兩個斜杠之間的是定義的正則內容,最后一個斜杠之后的是修飾符,這種方式比第一種簡單高效,所以通常使用第二種方式來定義正則。
其次,正則作為JS中的一個內置對象,它必然有一些屬性和方法,如下:
2.屬性
在控制台中打印一個正則對象如下:

可以看到它擁有global屬性,該屬性為布爾類型,用來表示該正則是否是全局匹配,ignoreCase屬性,布爾類型,用來指示是否忽略大小寫,lastIndex為number類型,用來表示上次匹配成功的位置,multiline,布爾類型,用來表示是否是多行匹配,source,string類型,用來表示正則的內容。
3.方法
通常對於一個正則對象來講,我們能夠使用的方法基本上有三個,即regObj.test,regObj.exec及regObj.compile
1)test方法,該方法用來測試某個字符串是否與正則匹配,匹配就返回true,否則返回false。
該方法接受一個字符串作為參數
代碼:
var reg=/boy(s)?\s+and\s+girl(s)?/gi; console.log(reg.test('boy and girl'));
結果在控制台上打印出了true。該方法也是最常用的一個方法。
2)compile方法
該方法的作用是能夠對正則表達式進行編譯,被編譯過的正則在使用的時候效率會更高,適合於對一個正則多次調用的情況下,如果對一個正則只使用一兩次,那么該方法沒有特別顯著的效應。
接受的參數也是一個正則。
代碼:
var reg=/[abc]/gi; console.log(reg.test('a')); reg=/[cde]/gi; console.log(reg.test('a')); reg.compile(reg); console.log(reg.test('a'));
結果:

被編譯的正則和沒有編譯的正則在測試結果上沒有任何區別,只是多次調用的效率上會更高一些。
3)exec方法
該方法屬於一個比較復雜的方法,它接受一個字符串,返回的是一個數組,數組中第0個元素是匹配的子字符串,第二個元素是正則中的第一個子分組匹配的結果(如果有子分組,即正則中存在用圓括號括起來的分組),第三個是正則中第二個子分組匹配的結果(如果有第二個子分組)...以此類推,如果沒有正則子分組,那么該數組長度僅僅為1,就是匹配到的那個子字符串。同時,返回的這個數組同時還是一個對象,它擁有兩個屬性,分別為index表示當前匹配到的子字符串所處的位置,input屬性表示被匹配的原始字符串。最后,該方法中的正則對象如果不是全局匹配,即沒有g修飾符,則每次調用只會從字符串開頭處匹配第一個結果,且每次調用結果都是一樣的。只有指定為全局匹配,才能夠按照從左往右依次去匹配,每次調用匹配一個結果,正則對象的lastIndex屬性前進到本次匹配的末尾位置,下回再調用的時候,會從lastIndex處開始匹配而不是從頭匹配。
全局匹配代碼:
var reg=/(\w)l(\w)/g; var str="hello world hello 123 hello programmer hello test"; var arr=reg.exec(str); while(arr){ console.dir(arr); console.log("lastIndex:"+reg.lastIndex); arr=reg.exec(str); }
結果如下:

非全局匹配代碼:
var reg=/(\w)l(\w)/; var str="hello world hello 123 hello programmer hello test"; var arr=reg.exec(str); var i=0; while(arr){ i++; if(i<=4){ console.dir(arr); console.log("lastIndex:"+reg.lastIndex); arr=reg.exec(str); } else{ break; } }
這里為了防止無限輸出,只輸出前5個結果,如下:

這個時候每次調用的結果都一樣,lastIndex根本沒有發生變化。
以上就是正則對象及其方法,其實在使用的過程中,JS中的String類型的對象也擁有一些和正則相關的方法,如下:
1)search方法
該方法是string對象的一個方法,用來查找第一次匹配的子字符串的位置,如果找到就返回一個number類型的index值,否則返回-1,它返回的只是第一次匹配的位置。
它接受一個正則或者子字符串為參數,這里我們只討論正則的情況。
代碼:
var str="hello world"; console.log(str.search(/o/g));
輸出結果為4,可以看到盡管具有多個匹配結果而且也聲明為全局匹配,但是還是返回的是第一個匹配到的子串的位置;
2)replace方法
該方法用來將字符串中的某些子串替換為需要的內容,接受兩個參數,第一個參數可以為正則或者子字符串,表示匹配需要被替換的內容,第二個參數為被替換的新的子字符串。如果聲明為全局匹配則會替換所有結果,否則只替換第一個匹配到的結果。
代碼如下:
var str="hello world,hello test"; console.log(str.replace(/hello/g,'hi'));
結果為hi world,hi test
如果將上面代碼中的g修飾符去掉,則返回的結果是hi world,hello test
3)split方法
該方法主要用來將一個字符串拆分成一個數組,它接受一個正則或者子字符(串)作為參數,返回一個數組,簡單情況下,我們不需要使用正則,只有在字符串拆分規則不統一的情況下才需要使用正則,如下:
var str="how|old*are you"; var arr=str.split(/\||\*|\s+/); console.log(arr);
這里需要將str拆分為單詞數組,由於每個單詞之間存在不一樣的分隔符,我們采取正則來匹配,結果如下:

4)match方法
該方法接受一個正則作為參數,用來匹配一個字符串,它的輸出結果在不是全局匹配的情況下和exec方法的結果一致即一個數組並帶有額外的屬性,如果采用全局匹配,則不返回任何和其被匹配字符串相關的信息,只返回匹配的結果。
非全局匹配代碼:
var reg2=/(\w)s(\w)/; var str2="ws1esr"; var result=str2.match(reg2); var i=0; while(result){ i++; if(i<=4){ console.dir(result); console.log("lastIndex:"+reg2.lastIndex); } else{ break; } }
結果如下:

非全局匹配下,結果和exec非全局匹配方法返回的完全一致,
全局匹配代碼:
var reg3=/(\w)s(\w)/g; var str4="ws1estqsa"; console.dir(str4.match(reg3));
結果如下:

可以看到,在全局匹配下的時候,它不同於exec方法,它會一次性將所有匹配結果以數組形式返回,且這個數組沒有其他屬性用來指向被匹配字符串的信息,而exec方法在全局匹配下每次返回的依然是本次匹配的結果數組,且這個數組中只包含本次匹配信息,同時又擁有指向被匹配字符串的信息,即match方法在全局匹配下一次性返回了所有匹配結果,而exec在全局匹配下返回的依然是當次匹配結果。
