• ES6类型扩展正则扩展


    正则表达式主要用于处理文本数据,即字符串。在ES6中,随着字符串操作的变更,正则表达式也进行了相应更新

    构造函数

    在ES5中,使用构造函数方式创建正则表达式的方式有两种

    第一种情况是,参数一是一个字符串,这时第二个参数表示正则表达式的修饰符(flag)

    var regexp = new RegExp('xyz', 'i');
    // 等价于
    var regex = /xyz/i;
    

    第二种情况是,参数是一个正则表示式,这时不能设置第二个参数,否则会报错

    var regex = new RegExp(/xyz/i);
    // 等价于
    var regex = /xyz/i;
    
    // 报错
    var regex = new RegExp(/xyz/, 'i');
    

    ES6改变了这种行为,可以使用第二个参数指定修饰符。而且,返回的正则表达式会忽略原有的正则表达式的修饰符,只使用新指定的修饰符

    console.log(new RegExp(/abc/ig, 'i').flags);//i
    

    flags属性

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

    var p1 = /[bc]at/i;
    // ES5的source属性返回正则表达式的正文
    console.log(p1.source);//'[bc]at'
    
    // ES6的flags属性返回正则表达式的修饰符
    console.log(p1.flags);//'i'
    

    正则方法

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

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

    String.prototype.match 调用 RegExp.prototype[Symbol.match]
    String.prototype.replace 调用 RegExp.prototype[Symbol.replace]
    String.prototype.search 调用 RegExp.prototype[Symbol.search]
    String.prototype.split 调用 RegExp.prototype[Symbol.split]
    

    u修饰符

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

    /^\uD83D/u.test('\uD83D\uDC2A') // false
    /^\uD83D/.test('\uD83D\uDC2A') // true
    

    点号

    元字符点号.在正则表达式中,含义是匹配除回车符\r、换行符\n、行分割符\u2028和段分隔符\u2029外的任意单个字符,但是对于码位大于0xFFFF的 Unicode 字符,点字符不能识别,必须加上u修饰符

    var text = "" ;
    console.log(text.length); // 2
    console.log(/^.$/u.test(text)); //true
    console.log(/^.$/.test(text));//false
    

    大括号

    ES6 新增了使用大括号表示 Unicode 字符,这种表示法在正则表达式中必须加上u修饰符,才能识别当中的大括号,否则会被解读为量词

    /\u{20BB7}/u.test('') // true
    /\u{61}/u.test('a') // true
    /\u{61}/.test('a') // false
    

    量词

    使用u修饰符后,所有量词都会正确识别码点大于0xFFFF的 Unicode 字符

    /{2}/u.test('') // true
    /{2}/.test('') // false
    

    预定义模式

    使用u修饰符后,预定义模式会正确识别码点大于0xFFFF的 Unicode 字符

    /^[\s\S]$/u.test('') // true
    /^[\s\S]$/.test('') // false
    

    字符串长度

    虽然ES6不支持字符串码位数量的检测,length属性仍然返回字符串编码单元的数量。但是利用[\s\S],再加上u修饰符,就可以正确检测字符串长度

    function codePointLength(str) {
      var ret = str.match(/[\s\S]/gu);
      return ret ? ret.length : 0;
    }
    
    var str = '';
    
    console.log(str.length); // 4
    console.log(codePointLength(str)); // 2
    

    unicode属性

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

    console.log(/^\uD83D/u.unicode); // true
    console.log(/^\uD83D/.unicode); // false
    

    检测支持

    u修饰符是语法层面的变更,尝试在不兼容 ES6 的 JS 引擎中使用它会抛出语法错误。可以写一个函数检测当前引擎是否支持u修饰符

    function hasRegExpU() {
      try {
        var pattern = new RegExp(".", "u");
        return true;
      } catch (ex) {
        return false;
      }
    }
    

    y修饰符

    ES6 为正则表达式添加了y修饰符,叫做“粘连”(sticky)修饰符。这个修饰符与g修饰符类似,都表示全局匹配,不同之处在于下一次匹配的起始位置,g修饰符是从剩余字符的第一个匹配位置开始,而y修饰符是从剩余字符的第一个位置开始

    var s = 'aaa_aa_a';
    var p1 = /a+/y;
    var p2 = /a+/g;
    
    // 第一次匹配,都是从第一个a开始,所以结果相同
    console.log(p1.exec(s)) // 'aaa'
    console.log(p2.exec(s)) // 'aaa'
    
    // 第二次匹配,一个从索引3开始,一个从索引4开始
    console.log(p1.exec(s)) // null
    console.log(p2.exec(s)) // 'aa'
    

    注意: y修饰符只有在调用 exec()和test()这两个正则匹配方法时,才会进行全局匹配;如果调用match()、replace()等字符串的方法时,不会进行全局匹配

    'a1a2a3'.match(/a\d/y) // ["a1"]
    'a1a2a3'.match(/a\d/gy) // ["a1", "a2", "a3"]
    

    sticky属性

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

    console.log(/a+/y.sticky); // true
    console.log(/a+/.sticky); // false
    

    检测支持

    function hasRegExpY() {
      try {
        var pattern = new RegExp(".", "y");
        return true;
      } catch (ex) {
        return false;
      }
    }
    

    逆序环视

    关于环视和正序环视的介绍移步至此

    一直以来,JavaScript 语言的正则表达式,只支持正序环视(又称先行断言),直到ES2018的出现,JS支持了逆序环视(又称后行断言)

    正序环视分为肯定正序环视和否定正序环视。肯定正序环视的记法是(?=n),表示前面必须是n才匹配;否定正序环视的记法是(?!n),表示前面必须不是n才匹配

    // a后面必须是b,才会执行匹配a
    console.log(/a(?=b)/.exec('abc'));//['a']
    console.log(/a(?=b)/.exec('ac'));//null
    
    // a后面必须不是b,才会执行匹配a
    console.log(/a(?!b)/.exec('abc'));//null
    console.log(/a(?!b)/.exec('ac'));//['a']
    
    // a后面必须是b,才会执行匹配ab
    console.log(/a(?=b)b/.exec('abc'));//['ab']
    

    逆序环视同样分为肯定逆序环视和否定逆序环视。肯定逆序环视的记法是(?<=n),表示后面必须是n才匹配;否定逆序环视的记法是(?<!n),表示后面必须不是n才匹配

    // b前面必须是a,才会执行匹配b
    console.log(/(?<=a)b/.exec('abc'));//['b']
    console.log(/(?<=a)b/.exec('bc'));//null
    
    // b前面必须不是a,才会执行匹配b
    console.log(/(?<!a)b/.exec('abc'));//null
    console.log(/(?<!a)b/.exec('bc'));//['b']
    
    // b前面必须是a,才会执行匹配ab
    console.log(/a(?<=a)b/.exec('abc'));//['ab']
    
    优秀文章首发于聚享小站,欢迎关注!
  • 相关阅读:
    第14章 位图和位块传输_14.1-14.3 位图基础
    第13章 使用打印机_13.2 打印图形和文字
    第13章 使用打印机_13.1 打印基础
    第12章 剪贴板_12.3 实现一个剪贴板查看器
    第12章 剪贴板_12.2 剪贴板的高级用法
    第12章 剪贴板_12.1 剪贴板的简单用法
    第11章 对话框_11.3 通用对话框
    第11章 对话框_11.2 非模态对话框
    第11章 对话框_11.1 模态对话框
    第5章 作业和进程池(2)
  • 原文地址:https://www.cnblogs.com/yesyes/p/15352131.html
Copyright © 2020-2023  润新知