正则实例对象的`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 关键字
- 第四节:对象遍历
- 第五节:对象继承
- 第六节:模块
- 第四章:正则表达式
- 第一节:概述
- 第二节:实例属性
- 第三节:实例方法
- 第一课时:测试
- 第二课时:执行
- 第四节:匹配规则
- 第一课时:字面量字符和元字符
- 第二课时:转义符
- 第三课时:特殊字符
- 第四课时:字符类
- 第五课时:预定义模式
- 第六课时:重复类
- 第七课时:量词符
- 第八课时:贪婪模式
- 第九课时:修饰符
- 第十课时:组匹配
- 第五节:字符串的实例方法
- 第一课时:匹配
- 第二课时:搜索
- 第三课时:替换
- 第四课时:分割