正則實例對象的`exec()`方法,用來返回匹配結果。如果發現匹配,就返回一個數組,成員是匹配成功的子字符串,否則返回`null`。
~~~
var s = '_x_x';
var r1 = /x/;
var r2 = /y/;
r1.exec(s) // ["x"]
r2.exec(s) // null
~~~
上面代碼中,正則對象`r1`匹配成功,返回一個數組,成員是匹配結果;正則對象`r2`匹配失敗,返回`null`。
如果正則表示式包含圓括號(即含有“組匹配”),則返回的數組會包括多個成員。第一個成員是整個匹配成功的結果,后面的成員就是圓括號對應的匹配成功的組。也就是說,第二個成員對應第一個括號,第三個成員對應第二個括號,以此類推。整個數組的`length`屬性等于組匹配的數量再加1。
~~~
var s = '_x_x';
var r = /_(x)/;
r.exec(s) // ["_x", "x"]
~~~
上面代碼的`exec()`方法,返回一個數組。第一個成員是整個匹配的結果,第二個成員是圓括號匹配的結果。
`exec()`方法的返回數組還包含以下兩個屬性:
* `input`:整個原字符串。
* `index`:模式匹配成功的開始位置(從0開始計數)。
~~~
var r = /a(b+)a/;
var arr = r.exec('_abbba_aba_');
arr // ["abbba", "bbb"]
arr.index // 1
arr.input // "_abbba_aba_"
~~~
上面代碼中的`index`屬性等于1,是因為從原字符串的第二個位置開始匹配成功。
如果正則表達式加上`g`修飾符,則可以使用多次`exec()`方法,下一次搜索的位置從上一次匹配成功結束的位置開始。
~~~
var reg = /a/g;
var str = 'abc_abc_abc'
var r1 = reg.exec(str);
r1 // ["a"]
r1.index // 0
reg.lastIndex // 1
var r2 = reg.exec(str);
r2 // ["a"]
r2.index // 4
reg.lastIndex // 5
var r3 = reg.exec(str);
r3 // ["a"]
r3.index // 8
reg.lastIndex // 9
var r4 = reg.exec(str);
r4 // null
reg.lastIndex // 0
~~~
上面代碼連續用了四次`exec()`方法,前三次都是從上一次匹配結束的位置向后匹配。當第三次匹配結束以后,整個字符串已經到達尾部,匹配結果返回`null`,正則實例對象的`lastIndex`屬性也重置為`0`,意味著第四次匹配將從頭開始。
利用`g`修飾符允許多次匹配的特點,可以用一個循環完成全部匹配。
~~~
var reg = /a/g;
var str = 'abc_abc_abc'
while(true) {
var match = reg.exec(str);
if (!match) break;
console.log('#' + match.index + ':' + match[0]);
}
// #0:a
// #4:a
// #8:a
~~~
上面代碼中,只要`exec()`方法不返回`null`,就會一直循環下去,每次輸出匹配的位置和匹配的文本。
正則實例對象的`lastIndex`屬性不僅可讀,還可寫。設置了`g`修飾符的時候,只要手動設置了`lastIndex`的值,就會從指定位置開始匹配。
- 第一章:變量與作用域
- 第一節:變量
- 第二節:執行環境及作用域
- 第三節:JS 解析機制
- 第四節:垃圾收集
- 第二章:深入函數
- 第一節:概述
- 第二節:函數聲明
- 第三節:函數調用
- 第四節:函數參數
- 第五節:函數返回值
- 第三章:面向對象
- 第一節:概述
- 第二節:對象聲明
- 第三節:this 關鍵字
- 第四節:對象遍歷
- 第五節:對象繼承
- 第六節:模塊
- 第四章:正則表達式
- 第一節:概述
- 第二節:實例屬性
- 第三節:實例方法
- 第一課時:測試
- 第二課時:執行
- 第四節:匹配規則
- 第一課時:字面量字符和元字符
- 第二課時:轉義符
- 第三課時:特殊字符
- 第四課時:字符類
- 第五課時:預定義模式
- 第六課時:重復類
- 第七課時:量詞符
- 第八課時:貪婪模式
- 第九課時:修飾符
- 第十課時:組匹配
- 第五節:字符串的實例方法
- 第一課時:匹配
- 第二課時:搜索
- 第三課時:替換
- 第四課時:分割