ES6 学习笔记 - 正则表达式

本文知识点主要整理自《深入理解 ES6(Understanding ECMAScript 6)》中文版实体书的内容,部分地方会加上自己的理解,同时书中叙述比较模糊的部分参考了阮一峰老师的《ECMAScript 6 入门》与网络上其他大佬们的博客、问答,篇幅有限无法一一列出,在此表示感谢。

u 修饰符

正则表达式默认是采用每个字符按照 16 位编码单元进行处理,为了支持 Unicode,ES6 新增了一个 u 修饰符。

const text = '?';

console.log(text.length); // 2
console.log(/^.$/.test(text)); // false
console.log(/^.$/u.test(text)); // true
复制代码

计算码位数量

ES6 中字符串的 length 属性仍然返回字符串编码单元的数量,但是可以通过正则表达式的 u 修饰符来获取码位的数量。

function codePointLength(text) {
    const result = text.match(/[\s\s]/gu);
    return result ? result.length : 0;
}

console.log(codePointLength('abc')); // 3
console.log(codePointLength('?bc')); // 3
复制代码

这个方式获取较长字符串的码位长度时效率会比较低。推荐使用字符串迭代器。

检测 u 修饰符

在不兼容 ES6 的 JavaScript 引擎中使用 u 修饰符会导致语法错误,因此建议在使用 u 修饰符之前,先对其安全性做检测。

function hasRegExpU() {
    try {
        const patten = new ReqExp('x', 'u');
        return true;
    } catch (e) {
        return false;
    }
}
复制代码

注意检测的时候一定要使用正则表达式的 构造函数

y 修饰符

y 修饰符曾经在 FireFox 上实现过,现在 ES6 将其加入了标准。

y 修饰符会影响正则表达式搜索中的 sticky 属性(粘滞、粘连)。与 g 修饰符一样,y 修饰符也是全局匹配,后一次匹配都从上一次匹配成功的位置之后开始。不同的是,g 只需要在剩余位置中存在匹配就会返回成功,y 只有在从起点位置存在匹配才行。

const s = 'aaa_aa_a';
const r1 = /a+/g;
const r2 = /a+/y;

r1.exec(s); // ['aaa']
r2.exec(s); // ['aaa']

r1.exec(s); // ['aa']
r2.exec(s); // null,第二次执行时起点是字符 '_',不存在匹配
复制代码

使用 y 修饰符,同时要注意

  • 只有调用 exec()test() 这些正则表达式对象的方法才会涉及 lastIndex 属性
  • 调用字符串方法,如 match() 等,不会触发粘滞行为

判断 y 修饰符是否存在

可以使用 sticky 属性进行判断,其值为布尔值。

sticky 属性是只读的,其值只由修饰符的存在性决定,无法在代码中修改。

检测 y 修饰符

u 修饰符一样,在使用 y 修饰符之前,最好对其安全性进行检查。

正则表达式的复制

在 ES5 可以通过给正则表达式的构造函数传入一个正则表达式来进行复制,在 ES6 中新增第二个参数,可以在复制时修改修饰符。

const r1 = /ab/i;
const r2 = new RegExp(r1, 'g');

console.log(r1.toString()); // '/ab/i'
console.log(r2.toString()); // '/ab/g'
复制代码

如果不传入第二个参数,则第二个的正则表达式与第一个会使用同样的修饰符。

flags 属性

ES6 新增了 flags 属性,能够直接返回正则表达式的修饰符。

const re = /ab/g;

console.log(re.source); // 'ab'
console.log(re.flags); // 'g'
复制代码

参考资料

  • Understanding ES6
  • ECMAScript 6 入门 - 正则表达式扩展

转载于:https://juejin.im/post/5c5d9f64e51d452704711440

你可能感兴趣的:(ES6 学习笔记 - 正则表达式)