我发现,如果只是总结,不回顾,不亲自动手尝试一下,印象是很不深刻的。(2018-12-06)
关于reg.exec
和string.match
方法
exec
是RegExp对象的方法,参数才是字符串,match
是字符串执行匹配正则表达式规则的方法,参数是正则表达,返回的都是数组;
在正则表达式没有全局标志g
时,二者的返回值是相同的
- 正则表达式中没有捕获组时,返回值是只有一个成员的数组,第一项是从起始位置开始寻找的第一个匹配项,无论执行多少次都是相同的(从位置
0
开始) - 正则表达式中有捕获组时,返回值是一个数组,第一项是从起始位置开始寻找的第一个匹配项,后续是匹配的捕获组,无论执行多少次都是相同的(从位置
0
开始)
const text = 'cat, bat';
let pattern = /.at/
pattern.exec(text)
// ["cat"]
pattern.exec(text)
// ["cat"]
text.match(pattern)
// ["cat"]
text.match(pattern)
// ["cat"]
let pattern2 = /.(at)/
pattern2.exec(text)
// ["cat", "at"]
pattern2.exec(text)
// ["cat", "at"]
在正则表达式含有全局标志g
时,二者的返回值不同
- 正则表达式中没有捕获组的时候
match
方法返回的数组成员是所有符合条件的匹配项,数组第一个成员存放第一个匹配项,数组第而个成员存放第二个匹配项…依次类推。无论执行多少次返回结果相同exec
方法永远返回值是只有一个成员的数组,第一项是第一个匹配项。但是当连续调用exec时,则每次的返回值都是在现有位置继续寻找的下一个匹配项。
let pattern3 = /.at/g
text.match(pattern3)
// ["cat", "bat"]
text.match(pattern3)
// ["cat", "bat"]
pattern3.exec(text)
// ["cat"]
pattern3.exec(text)
// ["bat"]
- 正则表达式有捕获组的时候
match
返回值与没有捕获组时相同,返回的数组由匹配项组成exec
返回值与没有g的捕获组正则表达式相同,第一项是从起始位置开始寻找的第一个匹配项,后续是匹配的捕获组,但如果执行多次返回值都是在现有基础上继续寻找的
let pattern4 = /.(at)/g
text.match(pattern4)
// ["cat", "bat"]
text.match(pattern4)
// ["cat", "bat"]
pattern4.exec(text)
// ["cat", "at"]
pattern4.exec(text)
// ["bat", "at"]
总结
总结一下:(g
代表全局标志,捕代表捕获组,每种情况的用→
连接的多个数组代表执行多次的结果)
(1)对于match
方法,是字符串的方法,返回值是数组
有g
的时候,会返回所有匹配项,没有g
的时候只会返回第一个匹配项
有捕获组的情况下,只有在没有g
的情况下,才会返回第一个匹配项的捕获组
- 有g无捕:
[匹配1, 匹配2, ...]
→[匹配1, 匹配2, ...]
- 有g有捕:
[匹配1, 匹配2, ...]
→[匹配1, 匹配2, ...]
- 无g无捕:
[匹配1]
→[匹配1]
- 无g有捕:
[匹配1, 捕获1-1, 捕获1-2...]
→[匹配1, 捕获1-1, 捕获1-2...]
(2)对于exec
方法,是RegExp对象的方法,返回值是数组
有g
的时候,exec
每次执行会呈现出递进的特性,否则每次执行的结果都是相同的
有捕获组的时候,总会返回当前匹配项的捕获组
- 有g无捕:
[匹配1]
→[匹配2]
- 无g无捕:
[匹配1]
→[匹配1]
- 有g有捕:
[匹配1, 捕获1-1, 捕获1-2...]
→[匹配2, 捕获2-1, 捕获2-2...]
- 无g有捕:
[匹配1, 捕获1-1, 捕获1-2...]
→[匹配1, 捕获1-1, 捕获1-2...]
常用
const date = '2018-10-07T11:48:47 Asia/zh-cn@@@@@@@@@2017-11-11T22:22:22 Asia/zh-cn';
要求匹配:
// ['2018', '10', '07', '11', '48', '47']
(1)想要获得第一个匹配项的全部的捕获组:
// 使用match方法,正则表达式不能由g
const reg = /(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d{2})/;
const result = date.match(reg).slice(1)
// 或者使用exec方法
// 正则有g没g都可以
const reg = /(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d{2})/;
const result = reg.exec(date).slice(1)
(2)获得所有的匹配项:
// 使用match方法
const reg = /(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d{2})/g;
const result = date.match(reg)
使用exec
方法需要循环调用,其实就没有必要了:
// 使用exec方法
const reg = /(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d{2})/g;
let result = [];
let temp = reg.exec(date);
while(temp) {
result.push(temp[0]);
temp = reg.exec(date)
}
(3)获得全部匹配项的全部捕获组
这种情况只能通过循环调用exec
方法,设置g
和捕获组实现
const reg = /(\d{4})-(\d+)-(\d+)T(\d+):(\d+):(\d{2})/g;
let result = [];
let temp = reg.exec(date);
while(temp) {
result.push(temp.slice(1);
temp = reg.exec(date)
}