zoukankan      html  css  js  c++  java
  • ES6 学习(5) 正则的扩展

    正则

    正则表达式的声明

     1 var regex = new RegExp('xyz', 'i');  // 第一个参数是字符串,第二个参数表示正则表达式的修饰符
     2  // 等价于
     3 var regex = /xyz/i;
     4 
     5  6 
     7 var regex = new RegExp(/xyz/i); // 参数是一个正则表达式,返回一个正则表达式的拷贝
     8 
     9 // 等价于
    10 var regex = /xyz/i;

    在ES6中,RegExp构造器函数第一个是正则对象,第二个参数可以是指定修饰符,而这在ES5中是不允许的,会报错;

    new RegExp(/abc/ig,"i").flags // i

    在这个表达式中,第二个参数修饰符i会覆盖原有正则对象的修饰符ig


    字符串的正则方法

      字符串对象共有4个方法,可以使用正则表达式: match(), replace(), search() 和 split()

      ES6将这4个方法,在语言内部全部调用RegExp的实例方法,从而做到所有与正则相关的方法,全都定义在RegExp对象上

    1 // String.prototype.match 调用 RegExp.prototype[Symbol.match]
    2 // String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
    3 // String.prototype.search 调用 RegExp.prototype[Symbol.search]
    4 // String.prototype.split 调用 RegExp.prototype[Symbol.split]

    u修饰符

      ES6 对正则表达式添加了u修饰符,含义为"Unicode 模式",用来正确处理大于\uFFFF的Unicode字符,也就是说,会正确处理四个字节的UTF-16 编码

     


    RegExp.prototype.unicode属性

       正则实例对象新增unicode属性,表示是否设置u修饰符

    1 const r1 = /hello/;
    2 const r2 = /hello/u;
    3 
    4 r1.unicode // false
    5 r2.unicode // true

      上面代码中,可以用unicode来判断是否设置了u修饰符


    y修饰符

      除了u修饰符,ES6还为正则表达式添加了y修饰符,叫做"粘连"(sticky)修饰符

      y修饰符的作用于g修饰符类似,也是全局匹配,后一次匹配都从上一次匹配成功的下一个位置开始,不同之处在于,g修饰符只要剩余位置中存在匹配就可,而y修饰符确保匹配必须从剩余的第一个位置开始,这也就是"粘连"的含义

    1 var s = 'aaa_aa_a';
    2 var r1 = /a+/g;
    3 var r2 = /a+/y;
    4 
    5 r1.exec(s) // ["aaa"]
    6 r2.exec(s) // ["aaa"]
    7 
    8 r1.exec(s) // ["aa"]     // 会从_aa_a,中的a开始匹配, g修饰符没有位置要求
    9 r2.exec(s) // null        // 会从 _aa_a,中的 _ 匹配,因此会返回null, y修饰符必须从头部开始

    RegExp.prototype.sticky属性

      与y修饰符相匹配,用来判断正则对象是否设置了y修饰符

    var r = /hello\d/y;
    
    r.sticky // true // 判断是否使用y修饰符

    RegExp.prototype.flags属性

      ES6 为正则表达式新增了flags属性,会返回正则表达式的修饰符

    1 // ES5 的 source 属性
    2 // 返回正则表达式的正文
    3 /abc/ig.source
    4 // "abc"
    5 
    6 // ES6 的 flags 属性
    7 // 返回正则表达式的修饰符
    8 /abc/ig.flags
    9 // 'gi'

    s修饰符: dotAll模式

      点(.)元字符,可以代表任意单个字符,但是有两个例外,一个是四字节的UTF-16,这个可以使用u修饰符解决,另一个是行终止符(该字符表示一行的终结 \n \r等) 

      /foo.bar/.test('foo\nbar') // false
      /foo.bar/s.test('foo\nbar') // true

      ES2018中引入s修饰符,使得.可以匹配任意单个字符,这被称为dotAll模式,即点(dot)代表一切字符,所以正则表达式还引入了一个dotAll属性,返回一个布尔值,表示该正则表达式是否处在dotAll模式

    1 const re = /foo.bar/s;
    2 // 另一种写法
    3 // const re = new RegExp('foo.bar', 's');
    4 
    5 re.test('foo\nbar') // true
    6 re.dotAll // true
    7 re.flags // 's'

    具名组匹配

      正则表达式使用圆括号进行组匹配 

    1 const RE_DATE = /(\d{4})-(\d{2})-(\d{2})/;
    2 
    3 const matchObj = RE_DATE.exec('1999-12-31');
    4 const year = matchObj[1]; // 1999
    5 const month = matchObj[2]; // 12
    6 const day = matchObj[3]; // 31

       ES2018 引入了具名组匹配(Named Capture Groups),允许为每一个组匹配指定一个名字,既便于阅读代码,又便于引用。

    1 const RE_DATE = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    2 
    3 const matchObj = RE_DATE.exec('1999-12-31');
    4 const year = matchObj.groups.year; // 1999
    5 const month = matchObj.groups.month; // 12
    6 const day = matchObj.groups.day; // 31

      如果具名组没有匹配到则该组的值为undefined;

      上面 ?<year> 相当于给每个组加了一个变量名,因此,也可以使用解构赋值

      即: let { groups: { one, two }} = /^( ?<one>.* ):( ?<two>.*)$/u.exec("foo:bar");   

      当字符串替换时,使用$<组名>引用具名组。

    1 let re = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/u;
    2 
    3 '2015-01-02'.replace(re, '$<day>/$<month>/$<year>')
    4 // '02/01/2015' 注意: replace的第二参数为字符串

      在正则表达式中还可以引用某个具名组匹配

     1 const RE = /^(?<word>[a-z]+)!\k<word>$/;
     2 RE.test('abc!abc') // true
     3 RE.test('abc!ab') // false
     4 
     5 // 数字引用(\1)依然有效。
     6 const RE_TWICE = /^(?<word>[a-z]+)!\1$/;
     7 RE_TWICE.test('abc!abc') // true
     8 RE_TWICE.test('abc!ab') // false
     9 
    10 // 同是还能两者一起用
    11 const RE1= /^(?<word>[a-z]+)!\k<word>!\1$/;
    12 RE1.test('abc!abc!abc') // true
    13 RE1.test('abc!abc!ab') // false

    String.prototype.matchAll

       一般来说,正则表达式在字符串.match方法中每次只能匹配到一个,但是 matchAll 一次性可以将所有的匹配项全部取出 返回一个伪数组; 之后可以用 ... 或 Array.from() 在转换成数组

    ———— 不生产代码,只是代码的搬用工

  • 相关阅读:
    每日站立会议08
    MAVEN常用命令
    android开发环境搭建
    阻止默认事件和阻止事件冒泡
    C#ActiveX安装项目
    System&Software
    poj 1386 Play on Words 有向欧拉回路
    poj 1033
    120.Triangle
    pandas中 transform 函数和 apply 函数的区别
  • 原文地址:https://www.cnblogs.com/newttt/p/11853484.html
Copyright © 2011-2022 走看看