ES9(2018)RegExp扩展

Posted 优小U

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ES9(2018)RegExp扩展相关的知识,希望对你有一定的参考价值。

1. dotAll 模式

正则表达式中,点(.)是一个特殊字符,代表任意的单个字符,但是有两个例外。一个是四个字节的 UTF-16 字符,这个可以用u修饰符解决;另一个是行终止符(line terminator character)。

  • U+000A 换行符(\\n)
  • U+000D 回车符(\\r)
  • U+2028 行分隔符(line separator)
  • U+2029 段分隔符(paragraph separator)
console.log(/foo.bar/.test('foo\\nbar')) // false
console.log(/foo.bar/s.test('foo\\nbar')) // true

在 ES5 中我们都是这么解决的:

console.log(/foo[^]bar/.test('foo\\nbar')) // true
// or
console.log(/foo[\\s\\S]bar/.test('foo\\nbar')) // true

那如何判断当前正则是否使用了 dotAll 模式呢?

const re = /foo.bar/s // Or, `const re = new RegExp('foo.bar', 's')` .
console.log(re.test('foo\\nbar')) // true
console.log(re.dotAll) // true
console.log(re.flags) // 's'

2. 具名组匹配

我们在写正则表达式的时候,可以把一部分用()包裹起来,被包裹起来的这部分称作“分组捕获”。

console.log('2020-05-01'.match(/(\\d{4})-(\\d{2})-(\\d{2})/))
//  ["2020-05-01","2020","05","01"]

这个正则匹配很简单,按照 match 的语法,没有使用 g 标识符,所以返回值第一个数值是正则表达式的完整匹配,接下来的第二个值到第四个值是分组匹配(2020, 05, 01)。

此外 match 返回值还有几个属性,分别是 index、input、groups。

  • index 匹配的结果的开始位置
  • input 搜索的字符串
  • group 一个捕获组数组 或 undefined(如果没有定义命名捕获组)

我们通过数组来获取这些捕获:

let t = '2020-05-01'.match(/(\\d{4})-(\\d{2})-(\\d{2})/)
console.log(t[1]) // 2020
console.log(t[2]) // 05
console.log(t[3]) // 01

在这里插入图片描述
上文中重点看下 groups 的解释,这里提到了命名捕获组的概念,如果没有定义 groups 就是 undefined。很明显,我们上述的返回值就是 `undefined 间接说明没有定义命名捕获分组。那什么是命名捕获分组呢?

console.log('2020-05-01'.match(/(?<year>\\d{4})-(?<month>\\d{2})-(?<day>\\d{2})/))

在这里插入图片描述
这段代码的返回值 groups 已经是 Object 了,这个 Object 的 key 就是正则表达式中定义的,也就是把捕获分组进行了命名。

3. 后行断言

在 ES9 之前 javascript 正则只支持先行断言,不支持后行断言。简单复习下先行断言的知识:

let test = 'hello world'
console.log(test.match(/hello(?=\\sworld)/))
// ["hello", index: 0, input: "hello world", groups: undefined]

这段代码要匹配后面是 world 的 hello,但是反过来就不成:

let test = 'world hello'
console.log(test.match(/hello(?=\\sworld)/))
// null

比如我们想判断前面是 world 的 hello,这个代码是实现不了的。在 ES9 就支持这个后行断言了:

let test = 'world hello'
console.log(test.match(/(?<=world\\s)hello/))
// ["hello", index: 6, input: "world hello", groups: undefined]

(?<...)是后行断言的符号,(?...)是先行断言的符号,然后结合 =(等于)、!(不等)、\\1(捕获匹配)。

以上是关于ES9(2018)RegExp扩展的主要内容,如果未能解决你的问题,请参考以下文章

ES9(2018)String 扩展 标签模板里字符串转义

ES9(2018)Object Rest & Spread

ECMAScript 2018(ES9)新特性简介

ES9对象和Promise的扩展

ES9(2018)for await...of

ES9(2018)Promise.prototype.finally()