首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

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

  • 24-12-16 15:24
  • 3642
  • 8343
www.oschina.net
鸿蒙原生应用开发者激励计划发布!最高获百万现金!点击立即参与

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,能点出哪些东西都不一定。

注:本文转载自www.oschina.net的linsk1998的文章"https://my.oschina.net/linsk1998/blog/16571848"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

104
前端
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top