最新消息:首页公告!

ES2024 正则表达式新特性 unicodeSets 解析及兼容方案

浏览 共有条评论 关键词:前端
新搜索营销

ES2024 对正则表达式添加了 v 修饰符,含义为 “Unicode 集合”,用来方便处理 Unicode 集合。v 修饰符是 u 修饰符的升级模式,使用了 v 修饰符就意味着包含了 u  修饰符的功能。比如 /\p{Emoji}/u 和 /\p{Emoji}/v 是等效的。

unicodeSets 的能力

unicodeSets 有以下 3 个功能:

\p 用来引用预定义的 Unicode 字符属性集合

比如 \p{RGI_Emoji} 匹配任何 RGI(Recommended for General Interchange)emoji 表情符号。

字符串集合三种集合操作,差异、相交和联合

 /^[\w--[a-g]]$/v.test('a') // false 
 /^[\w--[a-g]]$/v.test('i') // true
 

/[\p{ASCII}&&\p{Letter}]/v; // ASCII letters


/[[\p{ASCII}&&\p{Letter}]\p{Number}]/v; // ASCII letters, or any digit

集合中的多节点字符串,使用一个新的 \q 转义

/[\r\n\q{\r\n|NEWLINE}]/v; // Matches \r, \n, \r\n or NEWLINE

unicodeSets 的兼容问题

unicodeSets 可以被 babel 转译以支持低版本浏览器

比如 /[\p{ASCII}&&\p{Letter}]/v 经过 babel 转义后生成了 /[A-Za-z]/

正则对象还增加了 unicodeSets 属性,可以获取到是否有 v 修饰符

var a = /[\p{ASCII}&&\p{Letter}]/v;
console.log(a.flags);       // "v"
console.log(a.unicodeSets); // true

然而,如果使用 babel,转译后的代码将无法正确获取 flags 和 unicodeSets 了。

比如上述代码经过 babel 转义后变成了

var a = /[A-Za-z]/;
console.log(a.flags);       // ""
console.log(a.unicodeSets); // false

与浏览器直接运行不同。

unicodeSets 的出现还有可能引起旧有代码出现错误

if (xxx.unicode) {
    // do somthing
}

比如上述代码,判断正则表达式如果支持 unicode,则处理一些逻辑。而在有了 unicodeSets,这段代码就没有处理 unicodeSets 的情况。因为只有 v 标志时,unicode 为 false。

unicodeSets 兼容方案

解决 unicodeSets 有 2 个方案,一是通过 polyfill 处理,二是通过 babel 处理

假如使用 polyfill 处理,需要先将正则表达式字面量用 babel 转化为 new 表达式。然后再引入 polyfill。

这么做的好处是能做的和原生正则表达式一样,但是代价是:

  1. 需要大量修改原生功能,比如 String 的 replace、match 方法都需要 polyfill。这不符合尽量使用原生功能的原则。
  2. 正则表达式的 polyfill 要实现 \p 必然含有大量的字典数据,导致体积巨大。这不符合尽量不使用字典的原则。
  3. 根本找不到正则表达式的 polyfill 实现来用

因此建议通过 babel 处理正则表达式,并有限制的使用其功能。

在管理上

  • 禁止使用正则表达式的 unicodeSets 属性
  • 禁止使用正则表达式的 flags 属性
  • 通过 new 创建正则表达式,第二个参数不得含有 v 标志

看似在开发时稍加注意就行,其实不然。对大多数一线开发来说,要实现一个功能的步骤就是:百度、Ctrl+C、Ctrl+V,根本不会去考虑有什么问题,然后有兼容性的代码就被复制到项目中去了。像兼容性这样的问题本来就应该是架构层考虑的。因此我们在做前端基建时,除了要为开发人员配置 babel 外,还需使用 eslint 来限制开发人员的写法。

使用 eslint 插件 eslint-plugin-ts-compat 可以校验一些兼容性问题,用其中的 ts-compat/no-regexp-unicode-sets 规则处理 unicodeSets 问题。

这个插件是基于 typescript,只有在使用 typescript 的前提下才能使用。只有用了 typescript,才能知道类型,才能根据类型禁用属性。这也是我向来建议业务代码也要使用 typescript 的原因。有了 typescript,哪些能用,哪些不能用都一目了然;没有 typescript,能点出哪些东西都不一定。

转载请注明:可思数据 » ES2024 正则表达式新特性 unicodeSets 解析及兼容方案

人工智能数据标注服务
留言与评论(共有 条评论)
昵称:
匿名发表 登录账号
                 
   
验证码:
后台-系统设置-扩展变量-手机广告位-手机广告位-内容广告位三