这是我参与 8 月更文挑战的第 16 天,活动详情查看: 8月更文挑战
分组捕获,使用()进行数据分组,编号0代表整个匹配项,选择的分组从1号开始
或
{n}匹配最后字符重复了3次,并不能匹配整个单词重复三次的情况
var reg = /lian{3}/g;
var text = 'lianlianliannn';
var result = text.replace(reg,'x');
console.log(result);//lianlianx
如果我们要匹配lian连续出现3次的情况呢,正则表达式的分组'()'就帮我们解决了这个问题:
var reg = /(lian){3}/g;
var text = 'lianlianliannn';
var result = text.replace(reg,'x');
console.log(result);//xnn
反向引用
表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录(分组捕获)下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。
在js中正则匹配成功的字符串可以用3表示第三次匹配成功的字符
var reg = /(\d{4})-(\d{2})-(\d{2})/g;
var text = '2015-12-25'
var result = text.replace(reg,'$2/$3/$1');
console.log(result);//12/25/2015
忽略分组
默认是根据'()'全部捕获记录为99的,不希望捕获某些分组,只需要在分组内加上?:就可以了。
var reg = /(?:Lian)(\d{4})-(\d{2})-(\d{2})/g;
var text = 'Lian2016-12-05'
var result = text.replace(reg,'$2/$3/$1');
console.log(result);//12/05/2016
前瞻后顾断言
| 名称 | 正则 | 含义 |
|---|---|---|
| 正向前瞻 | exp(?=assert) | 后边是什么,我们匹配符合了exp部分的表达式,然后还不算完,必须也匹配断言部分('()'内部,'='后面的正则),才算成功 |
| 负向前瞻 | exp(?!assert) | 后边不是什么,我们匹配符合了exp部分的表达式,然后还不算完,必须也匹配断言部分('()'内部,'!'后面的正则),才算成功 |
| 正向后顾 | (?<=assert)exp | 后行断言,就是前面是什么 |
| 负向后顾 | (?<!assert)exp | 负向后行断言,就是前面不是什么 |
断言里面内容只是作为匹配的条件之一,也是必须的条件,但是匹配的本质只匹配"()"前面的正则
var reg = /\w(?=\d)/g;
var text = 'a2*3';
var result = text.replace(reg,'X');
console.log(result);//X2*3
题目
lastIndex
正则每次匹配并不是从头开始的,而是从上次的结果往后找,看看后面还有没有,有的话继续匹配,当然这必须是在'g'全局匹配的基础上,不然每次匹配都是从头开始的。
var reg1 = /\w/;
var reg2 = /\w/g;
console.log(reg1.test('a'));//true
console.log(reg1.test('a'));//true
console.log(reg1.test('a'));//true
//... 不管执行多少次都是true
//第一次匹配到'a'字符,匹配结果的最后一位字符也是'a','a'字符的下一个位置的index就是1了。类似的第二次匹配'b',匹配结果的最后一位字符也是'b','b'字符的下一个位置的index就是2
while(reg2.test('ab')){
console.log(reg2.lastIndex); // 1 2
}
console.log(reg2.test('ab'));//true
console.log(reg2.test('ab'));//true
console.log(reg2.test('ab'));//false
console.log(reg2.test('ab'));//true
console.log(reg2.test('ab'));//true
console.log(reg2.test('ab'));//false
//... 循环true true false
group
//match返回一个数组,下标0为匹配文本,1、2、3...匹配的为原子组
'pig'.match(/p((i)(g))/) // ["pig","ig","i","g"]
const str = 'name=pig'
str.match(/(?<key>.+)=(?<value>.+)/)
// 结果的groups
{
key: "name"
value: "pig"
}
转义\
const reg = new RegExp('\d') //这里我们传入的是字符串'\d' 那他匹配的是什么?
reg.test(1) // false
reg.test('\d') // true
在字符串中 \ 代表的是转义
'\d' === 'd' // true d经过 \的转义还是d,所以我们需要这样写
const reg2 = new RegExp('\\d')
reg.test(1) // true
//其实通过在控制台直接打印 reg我们也可以看到 得到的是/d/ 而不是/\d/
//所以当在对象创建正则中使用\d、\w等需要多加一个\。
分离标签内容
const str = `<span>pig1</span><span>pig2</span>dog<span>pig3</span>`
str.match(/<span>.+<\/span>/g)
// ["<span>pig1</span><span>pig2</span>dog<span>pig3</span>"]
因为正则时贪婪的所以它会尽可能的多匹配 就变成了开头的span 一直匹配到字符串结尾的span,所以我们要禁止贪婪
str.match(/<span>.+?<\/span>/g)
// ["<span>pig1</span>", "<span>pig2</span>", "<span>pig3</span>"] 尽可能的少匹配
日期替换
yyyy-mm-dd 格式,替换成 mm/dd/yyyy
//replace 第二个参数里用`$1、$2、$3`指代相应的分组
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, "$2/$3/$1");
console.log(result); // "06/12/2017"
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function() {
return RegExp.$2 + "/" + RegExp.$3 + "/" + RegExp.$1;
});
console.log(result); // "06/12/2017"
var regex = /(\d{4})-(\d{2})-(\d{2})/;
var string = "2017-06-12";
var result = string.replace(regex, function(match, year, month, day) {
return month + "/" + day + "/" + year;
});
console.log(result); // "06/12/2017"