博文类型: 学习向
背景: 学习ES6语法并做学习笔记
目标: 跟着ES6教程实操,并记录实操结果
一、u 修饰符
作用:
es5 正则无法识别 4 个字节的字符(unicode 大于\uFFFF),es6 新增 u 修饰符后就可以识别 4 个字节的字符。
console.log(/^\uD83D/u.test("\uD83D\uDC2A"));
//false \uD83D\uDC2A识别为一个字符
console.log(/^\uD83D/.test("\uD83D\uDC2A"));
//true \uD83D\uDC2A识别为两个字符
1.点字符
作用:
点字符在正则表达式中的含义是除了换行符以外的任意单个字符。对于码点大于 0xFFFF 的字符,点字符不能识别,必须加上 u 修饰符。
let val = "𠮷a"; //码点:0x20BB7,UTF-16:0xD842 0xDFB7,十进制:55362 57271
console.log(/^.$/.test(val));
//false
console.log(/^.$/u.test(val));
//true
2.Unicode字符表示法
作用:
es6新增了使用大括号表示Unicode字符,但是正则表达式中必须要加上u,否则会被识别为量词。
console.log(/\u{61}/.test("a"));
//false
console.log(/\u{61}/u.test("a"));
//true
3.量词
作用:
匹配连续字符。
console.log(/a{2}/.test("a"));
//false
console.log(/a{2}/.test("aa"));
//true
console.log(/𠮷{2}/.test("𠮷"));
//false
console.log(/𠮷{2}/u.test("𠮷𠮷"));
//true
4.预定义模式
作用:
\S是预定义模式,他能匹配所有不是空格的字符。但是只有加了u修饰符,他才能正确匹配码点大于0xFFFF的字符串。
console.log(/^\S$/.test("𠮷"));
//false
console.log(/^\S$/u.test("𠮷"));
//true
二、y 修饰符
1.基本使用
作用:
y修饰符,叫作“粘连”修饰符。y修饰符与g修饰符类似,都是全局匹配,不同之处在于,g修饰符第二次匹配只需要剩余部分存在匹配就可以,y修饰符的第二次匹配则需要从剩余部分的第一个位置开始匹配。
let a='aaa_aa_a'
let r1=/a+/g
let r2=/a+/y
console.log(r1.exec(a));
//['aaa']
console.log(r2.exec(a));
//['aaa']
console.log(r1.exec(a));
//['aa']
console.log(r2.exec(a));
//null
debugger
解释:
第一次匹配都能获得‘aaa’,剩余字段‘_aa_a’。
第二次匹配,g修饰符可以直接在剩余字段中进行匹配,而y修饰符则会从剩余字符的第一个位置开始匹配,剩余字段的第一个字符与匹配规则不符,则返回null。
2.lastIndex属性
作用:
开始匹配的位置
let a='aaa_aa_a'
let r2=/a+/y
r2.lastIndex=4
let b=r2.exec(a)
console.log(b.index);
//4
console.log(r2.exec(a));
//null
r2.lastIndex=7
console.log(r2.exec(a));
//['a']
debugger
解释:
第一次匹配位置计数是从0开始的,r2.lastIndex=4表示从位置计数为4的字符(包含位置计数为4的字符)开始匹配。匹配规则可以匹配到’aa’,匹配到的位置计数为4(b.index)。
第二次匹配是从位置计数6开始的,位置计数6的字符是’_‘,不符合匹配规则,返回null。
第三次匹配从位置计数是7的字符开始匹配,可以匹配到’a’。
3.g、y修饰符合用
作用:
返回全部符合规则的连续的字符。
let r1=/a\d/g
let r2=/a\d/y
console.log('a1a2a3 ' .match(r1));
//['a1', 'a2', 'a3']
console.log('a1a2a3 ' .match(r2));
//['a1']
console.log('a1a2a3 ' .match(r2));
//['a2']
console.log('a1a2a3 ' .match(r2));
//['a3']
console.log('a1a2a3 ' .match(/a\d/gy));
//['a1', 'a2', 'a3']
console.log('a1a2a3 ' .match(/a\d/yg));
//['a1', 'a2', 'a3']
debugger
解释:
g修饰符能够返回所有与规则向匹配的字符,y修饰符能够返回第一个从第一个位置开始匹配规则的字符。gy能够返回从第一个位置开始符合匹配规则的所有字符,且gy与yg不用区分先后。
4.sticky属性
作用:
是否用了y修饰符
let r1=/a\d/g
let r2=/a\d/y
console.log(r1.sticky);
//false
console.log(r2.sticky);
//true
debugger
5.falgs属性
作用:
返回正则表达式的修饰符
let r1=/a\d/gy
console.log(r1.flags);
//gy
debugger
6.source属性
作用:
返回正则表达式正文
let r1=/a\d/gy
console.log(r1.source);
//a\d
debugger
三、s 修饰符:dotAll模式
作用:
使得点字符可以匹配所有的字符。
console.log(/foo.bar/.test('foo\nbar'));
//false
console.log(/foo.bar/s.test('foo\nbar'));
//true
debugger
解释:
点字符可以匹配任意单个字符,但是无法匹配行终止符。
以下四个属于行终止符:
U+000A 换行符(\n)
U+000D 回车符(\r)
U+2028 行分隔符( line separator)
U+2029 段分隔符( paragraph separator)
s修饰符可以使得点字符匹配行终止符。
1.dotAll属性
作用:
返回正则表达式是否处于dotAll模式下。
let r1=/foo.bar/s
console.log(r1.dotAll);
//true
debugger
解释:
点字符(dot)可以代表一切字符,则可称为 dotAll模式。
四、各种断言
1.先行断言
作用:
x只有在y前面才匹配(正则:/x(?=y)/)。
let r1=/\d+(?=%)/g
console.log(r1.exec('100%222%123456'));
//['100']
console.log(r1.exec('100%222%123456'));
//['222']
debugger
解释:
匹配在百分号前的数字。
2.先行否定断言
作用:
x只有不在y前面才匹配(正则:/x(?!y)/)
let r1=/\d+(?!%)/g
console.log(r1.exec('100%222%123456'));
//['10']
console.log(r1.exec('100%222%123456'));
//['22']
console.log(r1.exec('100%222%123456'));
//['123456']
debugger
解释:
匹配不在百分号前一位的数字。
3.后行断言
作用:
x只有在y后面才匹配(正则:/(?<=y)x/)
let r1=/(?<=\$)\d+/g
console.log(r1.exec('100$222$123456'));
//['222']
console.log(r1.exec('100$222$123456'));
//['123456']
console.log(r1.exec('100$222$123456'));
//null
debugger
解释:
匹配美元符号后的数字。
4.后行否定断言
作用:
x只有不在y后面才匹配(正则:/(?<!y)x/)
let r1=/(?<!\$)\d+/g
console.log(r1.exec('100$222$123456'));
//['100']
console.log(r1.exec('100$222$123456'));
//['22']
console.log(r1.exec('100$222$123456'));
//['23456']
debugger
解释:
匹配美元符号前的数字。
五、具名组匹配
1.简介
作用:
不再被顺序所束缚,将匹配出的数据赋予特定的含义。(正则:?<名字>)
let r1=/(\d{4})-(\d{2})-(\d{2})/
let re=r1.exec('1997-10-29')
console.log(re[1]);
//1997
console.log(re[2]);
//10
console.log(re[3]);
//29
let r2=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let re2=r2.exec('1997-10-29')
console.log(re2.groups.year);
//1997
console.log(re2.groups.month);
//10
console.log(re2.groups.day);
//29
2.解构赋值和替换
1)解构赋值
作用:
能够通过解构赋值将具名匹配的结果赋值给变量。
let r1=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let {groups:{year,month,day}}=r1.exec('1997-10-29')
console.log(year);
//1997
console.log(month);
//10
console.log(day);
//29
2)替换
//参数为变量
let r1=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let re='1997-10-29'.replace(r1,'$<day>/$<month>/$<year>')
console.log(re);
//29/10/1997
//参数为函数
let r1=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
let re='1997-10-29'.replace(r1,(
matched,//整个匹配结果
capture1,//第一个组匹配
capture2,//第二个组匹配
capture3,//第三个组匹配
position,//匹配开始的位置
s,//原字符串
groups//具名组构成的一个对象
)=>{
console.log(matched,capture1,capture2,capture3,position,s,groups);
debugger
})
//1997-10-29 1997 10 29 0 1997-10-29 {year: '1997', month: '10', day: '29'}
3.引用
作用:
可以在正则表达式中引用具名组匹配(正则:\k<名字>或\第几个具名组)
let r1=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-\k<year>/
let r2=/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})-\1/
let re1=r1.test('1997-10-29-1992')
console.log(re1);
//false
let re2=r1.test('1997-10-29-1997')
console.log(re2);
//true
let re3=r2.test('1997-10-29-1992')
console.log(re3);
//false
let re4=r2.test('1997-10-29-1997')
console.log(re4);
//true
解释:
可以通过两种方式在正则表达式中引用具名组匹配。
1.\k<组名>
2.\组序号(序号从1开始)