• 【ES6】学习笔记:正则扩展


    博文类型: 学习向
    背景: 学习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
    • 2
    • 3
    • 4
    • 5

    1.点字符


    作用:
    点字符在正则表达式中的含义是除了换行符以外的任意单个字符。对于码点大于 0xFFFF 的字符,点字符不能识别,必须加上 u 修饰符。

    let val = "𠮷a"; //码点:0x20BB7,UTF-16:0xD842 0xDFB7,十进制:55362 57271
    console.log(/^.$/.test(val));
    //false
    
    console.log(/^.$/u.test(val));
    //true
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.Unicode字符表示法


    作用:
    es6新增了使用大括号表示Unicode字符,但是正则表达式中必须要加上u,否则会被识别为量词。

    console.log(/\u{61}/.test("a"));
    //false
    
    console.log(/\u{61}/u.test("a"));
    //true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    4.预定义模式


    作用:
    \S是预定义模式,他能匹配所有不是空格的字符。但是只有加了u修饰符,他才能正确匹配码点大于0xFFFF的字符串。

    console.log(/^\S$/.test("𠮷"));
    //false
    
    console.log(/^\S$/u.test("𠮷"));
    //true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    二、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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    解释:
    第一次匹配都能获得‘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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    解释:
    第一次匹配位置计数是从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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    解释:
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    5.falgs属性


    作用:
    返回正则表达式的修饰符

    let r1=/a\d/gy
    console.log(r1.flags);
    //gy
    
    debugger
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6.source属性


    作用:
    返回正则表达式正文

    let r1=/a\d/gy
    console.log(r1.source);
    //a\d
    
    debugger
    
    • 1
    • 2
    • 3
    • 4
    • 5

    三、s 修饰符:dotAll模式

    作用:
    使得点字符可以匹配所有的字符。

    console.log(/foo.bar/.test('foo\nbar'));
    //false
    
    console.log(/foo.bar/s.test('foo\nbar'));
    //true
    
    debugger
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    解释:
    点字符可以匹配任意单个字符,但是无法匹配行终止符
    以下四个属于行终止符:
    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
    
    • 1
    • 2
    • 3
    • 4
    • 5

    解释:
    点字符(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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    解释:
    匹配在百分号前的数字。

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    解释:
    匹配不在百分号前一位的数字。

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    解释:
    匹配美元符号后的数字。

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    解释:
    匹配美元符号前的数字。

    五、具名组匹配

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    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'}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    解释:
    可以通过两种方式在正则表达式中引用具名组匹配。
    1.\k<组名>
    2.\组序号(序号从1开始)

  • 相关阅读:
    美团分布式 ID 框架 Leaf 介绍和使用
    网上零食销售系统(Java;JSP;JDBC)附源码+数据库+论文
    八个开源免费单点登录(SSO)系统
    LintCode 3. 统计数字 Python
    【树】B树与B+树
    美团财务科技Java后端一面:面向对象、类加载过程、全限定类名相同的类是否可以同时被加载
    从 0 开始编译 Android 系统源码
    Nashorn引擎导致metaspace oom
    博客系统(升级(Spring))(二)获取当前用户信息、对密码进行加密、设置统一数据格式、设置未登录拦截、线程池
    TP5 模型查询的返回值、返回值的判断以及所使用的SQL
  • 原文地址:https://blog.csdn.net/qq_43372138/article/details/125559243