小览 ES6-ES2019 中正则表达式的新发展
栏目: JavaScript · 发布时间: 7年前
内容简介:在此前的本文尝试走马观花,一瞥这些特性,看能否籍此简化我们的开发。
在此前的 《JS正则表达式--从入门到精分》 一文中,曾经较完整的介绍过 Javascript 中正则表达式的用法。而从 ES6(ES2015) 开始,借助 Babel 等标志性的工具,JS 的发展似乎也不想重蹈 Flash 时代的无所作为,走上了每年一个小版本的快车道;在此过程中,正则表达式也陆续演化出一些新的特性。
本文尝试走马观花,一瞥这些特性,看能否籍此简化我们的开发。
ECMAScript 和 TC39
虽然可能是大家普遍了解的事情,但这些称呼反复出现,可能还是需要稍微解释一下先。
ECMA 指的是 “欧洲计算机制造商协会”(European Computer Manufacturers Association);现在也称为 “ECMA 国际”(ECMA International),定位为一家国际性会员制度的信息和电信标准组织。
1996 年 11 月,JavaScript 的创造者 Netscape 公司,决定将 JavaScript 提交给 ECMA,希望这种语言能够成为国际标准。次年,ECMA 发布 262 号标准文件(ECMA-262)的第一版,规定了浏览器脚本语言的标准,并将这种语言称为 ECMAScript (简称 ES)。
此后该标准应用广泛,JavaScript、JScript、ActionScript 等都算是 ECMA-262 标准的实现和扩展。
从 1997 年至 2009 年,陆续发布了 ES1 ~ ES5;其中 ES4 其实是偏向于 Adobe 的 ActionScript 风格的实践设计的,但最终也随着 Flash 被市场上其他厂商封杀,以改动过大为名不了了之,但其中一些特性被后来的 ES6 继承。
2015年,可以说迄今最重要的一个版本 ES6,也就是 ES2015(ES6 的第一个版本) 发布。由各个主流浏览器厂商的代表组成 ECMA 第 39 号技术专家委员会(Technical Committee 39,简称 TC39),负责制订新的 ECMAScript 标准。
新的语法从提案到变成正式标准,需要经历五个阶段。每个阶段的变动都需要由 TC39 委员会批准:
-
Stage 0 - Strawman(展示阶段)
-
Stage 1 - Proposal(征求意见阶段)
-
Stage 2 - Draft(草案阶段)
-
Stage 3 - Candidate(候选人阶段)
-
Stage 4 - Finished(定案阶段)
以上这几个也就是我们之前使用 Babel 转译 工具 时会引入 babel-preset-stage-0 等预置方案的原由,当然随着 Babel 7 的发布,这些方案都被统一到了 @babel/preset-env 中。
ES6 中的正则表达式特性
以下特性首次在 ES6 中出现:
-
“粘性”修饰符
/y -
unicode 修饰符
/u -
正则表达式对象上的新属性
flags -
用构造函数
RegExp()拷贝正则表达式
“粘性”修饰符 /y
修饰符 /y 只将正则表达式的每个匹配锚定到前一个匹配的末尾
简单的说,这主要与正则表达式对象上的 lastIndex 属性有关 -- 其与 /g 或 /y 的搭配,会产生不同的效果。
在不设置修饰符,或只设置了 /g 修饰符的情况下,只要目标字符串(或上一次匹配的剩余部分)中存在匹配就可以。
而 /y 修饰符则告知正则表达式,只能不偏不倚的从字符串的 lastIndex 那个位置去匹配,这也就是“粘性、粘连”的涵义。
以 exec() 的使用为例:
当然,一般情况下 -- 比如第一次运行匹配,或不特别设置 lastIndex 时, /y 的功效大抵和 ^ 起始匹配符相同,因为此时 lastIndex 为 0 :
需要注意的是,如果同时设置了 /g 和 /y ,则只有 /y 会生效。
sticky 属性
与 /y 修饰符相配套,ES6 的正则表达式对象多了 sticky 属性,表示是否设置了 /y 修饰符:
unicode 修饰符 /u
这里简单解释一下 Unicode,其目标是为世界上每一个字符提供唯一标识符,该唯一标识符可称为 码点(code point) 或 字符编码(character encode)。
在 ES6 之前, JS 的字符串以 16 位字符编码(UTF-16)为基础。每个 16 位序列(相当于2个字节)是一个 编码单元(code unit,可简称为码元) ,用于表示一个字符。字符串所有的属性与方法(如 length 属性与 charAt() 方法等)都是基于这样 16 位的序列。
本来 JS 允许采用 \uxxxx 形式表示一个常用的 unicode 字符,其中的 4 个十六进制数字表示字符的 unicode 码点:
同时,这种表示法只能表示码点局限于 0x0000 ~ 0xFFFF 之间的字符。超出这个范围的字符,必须用两个码元连接的形式(称为 surrogate-pairs,代理对)表示一个码点:
这就导致了一个问题,对于一些超出 16 位 0xFFFF 的 unicode 字符,传统的方法就会出错;比如直接在 \u20BB7 ,JS 会理解成 \u20BB + 7 ;所以会显示成一个特殊字符,后面跟着一个 7。
对此 ES6 做出了改进,将 unicode 编码放入大括号(这种语法称为 unicode 码点转义符),就可以正确解读字符了:
同样的例子:
此中的转换对应关系,这篇文章( https://blog.csdn.net/hherima/article/details/38961575 )做了比较清楚的探寻,感兴趣的话可以结合文末的资料进行研究;本文不展开掰哧,能体会示例即可。
书归正传,在 ES6 的正则中:
修饰符 /u 将正则表达式切换为特殊的 Unicode 模式
在 Unicode 模式下,既可以使用新的大括号 unicode 编码点转义符表示范围更大的字符,也可以继续使用 UTF-16 码元。该模式具有如下特征:
-
“单独代理”(lone surrogates)特性:
-
可以将码点放入正则的字符类中:
-
点操作符匹配码点,而非码元
-
数量描述符也同样匹配到码点
正则表达式对象上的新属性 flags
新增的 flags 属性,会返回正则表达式的修饰符
用 RegExp() 拷贝正则表达式
正则表达式构造函数的传统签名是 newRegExp(pattern:string,flags='') ,比如:
ES6中,新增的用法是 newRegExp(regex:RegExp,flags=regex.flags) :
这就提供了一种拷贝已有正则表达式,或更改其修饰符的方法。
ES2018/ES2019 中的新特性
在 ES2018 - ES2019 中,又增加了一些特性:
-
命名捕获组
-
反向引用
-
反向断言
-
unicode 属性转义
-
dotAll 修饰符
/s
命名捕获组
此前的正则表达式操作中,采用的是“编号捕获组”(Numbered capture groups)匹配字符串并将之分组,比如:
这种方式无论从易用性还是复杂度方面都不太理想,尤其当字段过多、存在嵌套等情况时;如果改动了正则表达式还容易忘记同步改变分散在各处的编号。
ES6 带来的“命名捕获组”(Named capture groups),则可以通过名称来识别捕获的分组
-
其格式如
(?<year>[0-9]{4}) -
通过捕获结果中的
groups.year属性取出 -
任何匹配失败的命名组都将返回 undefined
这还为 replace() 方法提供了额外的便利,注意其语法:
反向引用(Backreferences)
正则表达式中的 \k<name> 表示这样的意思:根据前一次匹配到的命名捕获组中的名称,匹配相应的字符串,比如:
这种称为 反向引用 的语法,对于编号捕获组同样适用:
两掺儿的,也没问题:
反向断言(lookbehind assertions)
根据之前文章的介绍,JS 中已经支持了“正向断言”(Lookahead assertions),或称为正向查找。
-
x(?=y)匹配'x'仅仅当'x'后面跟着'y'。称为正向肯定查找 -
x(?!y)匹配'x'仅仅当'x'后面不跟着'y'。称为正向否定查找
ES2018 引入了反向断言(lookbehind assertions),与正向断言的工作方式相同,只是方向相反
同样也分为两种子类型:
-
y(?<=x)匹配'x'仅仅当'x'前面挨着'y'。称为 反向肯定查找
-
y(?<!x)匹配'x'仅仅当'x'前面不挨着'y'。称为 反向否定查找
unicode 属性转义
在 ES6 的 /u 修饰符基础上,ES2018 添加了 "unicode 属性转义"(Unicode property escapes) -- 形式为 \p{...} 及 \P{...} ,分别表示“包含”和“不包含”
从目的和形式上这很类似于用 \s 来匹配空格等 whitespace,而 \p{} 和 \P{} 花括号中的部分称为 "unicode 字符属性" (Unicode character properties),让正则表达式有了更好的可读性。
所谓“unicode 字符属性”,是指在 Unicode 标准中,每个字符都有用于描述其性质的元数据: properties ,比如:
-
Name: 一个唯一的名称,由大写字母、数字、连字符、空格组成,如: -
A: Name = LATIN CAPITAL LETTER A -
:grinning:: Name = GRINNING FACE -
General_Category: 分类的字符,如: -
x: General Category = Lowercase Letter -
$: General Category = Currency Symbol -
White_Space: 用于标记不可见的空格、制表符、换行等字符,如: -
\t: White Space = True -
π: White Space = False -
Age: Unicode 标准的版本号,如: -
€: Age = 2.1 -
Block: 码点的一个连续范围,不会重复,命名也是唯一的,如: -
S: Block = Basic_Latin (range U+0000..U+007F) -
:grinning:: Block = Emoticons (range U+1F600..U+1F64F) -
Script: 一个字符集合,用于一个或多个书写系统 -
α: Script = Greek -
Д: Script = Cyrillic -
某些 script 支持多个书写系统,比如 Latin script 支持 English, French, German, Latin 等
-
某些语言可以用由多种 script 支持的多种替代书写系统书写。例如,土耳其语在 20 世纪早期转变为 Latin script 之前就使用了 Arabic script。
-
举例来说:
另外几个例子:
dotAll 修饰符 /s
我们通常会在很多正则表达式中见到一种 [\s\S] 的匹配小技巧,这种看似多余的写法其实是为了弥补 . 标记无法在多行的情况下实现正确匹配的缺憾。
修饰符 /s 解决了这个问题,所以也称为 dotAll 修饰符。
关于 . 标记,顺便一提的是:
参考资料:
-
《JS正则表达式--从入门到精分》 https://mp.weixin.qq.com/s?__biz=MzI0MDYzOTEyOA==&mid=2247483694&idx=1&sn=e79f23c86e48b6a85d30d612e1d5a2eb&chksm=e9168cd9de6105cf647ceabac1a2ee737d0867e7b3cdab243e3cd889b295e3ab9666820ad02d
-
http://exploringjs.com/es6/ch regexp.html#sec regexp
-
http://exploringjs.com/es2018-es2019/toc.html
-
http://www.cnblogs.com/dandelion-drq/p/js regular expression_note.html
-
http://www.appui.org/2496.html
-
https://stackoverflow.com/questions/4542304/what-does-regex-flag-y-do
-
http://www.cnblogs.com/detanx/p/es6zz.html
-
http://www.cnblogs.com/xiaohuochai/p/7230328.html
-
https://www.princeton.edu/~mlovett/reference/Regular-Expressions.pdf
-
https://unicodebook.readthedocs.io/unicode_encodings.html#utf-16-c
-
https://docs.microsoft.com/zh-cn/previous-versions/8k5611at(v=vs.110)
-
https://blog.csdn.net/hherima/article/details/38961575
-
https://arui.tech/es2018-new-features/#UnicodeUnicode property escapes
-
https://github.com/tc39/proposal-regexp-unicode-property-escapes
-
http://caibaojian.com/es6/
-
https://zhuanlan.zhihu.com/p/27762556
-
https://babeljs.io/docs/en/babel-preset-env
--End--
搜索 fewelife 关注公众号
转载请注明出处
以上所述就是小编给大家介绍的《小览 ES6-ES2019 中正则表达式的新发展》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Designing for Emotion
Aarron Walter / Happy Cog / 2011-10-18 / USD 18.00
Make your users fall in love with your site via the precepts packed into this brief, charming book by MailChimp user experience design lead Aarron Walter. From classic psychology to case studies, high......一起来看看 《Designing for Emotion》 这本书的介绍吧!