在 ECMAScript 2018 中,新增了一个非常有用的特性:Regex 反向断言。不知道大家是否有对正则表达式(Regex)有所接触,如果没有,那么我简单的介绍一下。正则表达式是一种用于匹配字符串的工具,它可以帮助我们从数据中筛选出我们需要的内容。在日常前端开发中,我们必须要经常用到正则表达式。Regex 反向断言允许我们在匹配字符串时,根据后面的内容选择是否要匹配当前的字符串。这个新特性在一些场景下可以让我们的代码更加简洁,且易于维护。
1. 反向断言是什么?
在了解什么是反向断言之前,我们先来看一下正向断言。
正向断言:
const str = 'abc123' if (/\d/.test(str)) { console.log('匹配到数字') }
以上代码中,我们使用 test() 方法去匹配字符串,如果匹配到了任意数字,那么就会输出“匹配到数字”。正向断言的位置在 (?=) 中,表示断言后面的位置必须要匹配这个表达式,才会符合断言。如果是在否定断言中,那么位置就变成了 (?!=) 。
反向断言的用法和正向断言非常相似,只不过位置是 (?<=) 和 (?<!) 。下面我们就来看一个反向断言的实例。
反向断言:
const str = 'abc123' if (/(?<=\d{3})\w+/.test(str)) { console.log('匹配到字母') }
我们在这个表达式中,要匹配的内容是字母,但是字母前面必须是三个数字。(?<=) 表示我们在匹配表达式的时候,必须要满足后面的表达式才行。类似的,如果是否定断言,那么位置则变成了 (?<!) 。
从这个简单的例子可以看到,反向断言的作用就是为了在匹配字符串的时候,依据后面的内容去决定是否需要匹配当前的内容。
2. 如何使用反向断言?
既然我们已经知道什么是反向断言,那么我们就可以开始用它来编写一些实用的代码了。通过反向断言我们可以轻松实现一些常规匹配难以实现的匹配操作。
以电话号码为例,假设我们的电话号码为:(123) 456-7890,现在我们希望匹配到电话号码后面的后缀,需要用到反向断言来实现。
const str = '(123) 456-7890' const suffix = /(?<=\-\d{4,5})\d+/.exec(str) console.log(suffix) // 输出 ["7890"]
在这个例子中,我们使用反向断言来匹配电话号码后面的数字。我们要求在一个匹配中,有以 " - " 符号隔开的 4 或者 5 个数字,然后后面又跟上了一些数字。这些数字就是我们需要的后缀信息。
另一个例子是可以从多个内容中提取出我们所需要的内容,虽然这个例子看上去有些复杂,但是它能让我们更好的理解如何使用反向断言来处理多个不同的内容。
const str = '3a3b3c2d2e2f' const nums = /(?<=(\d)+\w)./g.exec(str) console.log(nums[0].slice(1)) // 输出 "a" console.log(nums[1].slice(1)) // 输出 "b" console.log(nums[2].slice(1)) // 输出 "c" console.log(nums[3].slice(1)) // 输出 "d" console.log(nums[4].slice(1)) // 输出 "e" console.log(nums[5].slice(1)) // 输出 "f"
这个例子中,我们要从多个内容中提取出在数字后面的字母内容。我们用的是 (.+?) 作为我们的匹配模式,让表达式去匹配任意数目的字符。使用反向断言,方便我们在匹配过程中,选择一些我们需要的内容。通过这种方式,我们可以轻松的从数据中获取到我们想要的内容。
3. 总结
ECMAScript 2018 新增了反向断言的特性,我们可以根据后面的内容选择是否要匹配当前的字符串,让匹配过程更加高效,代码更加简洁易于维护。虽然这个新特性目前的兼容性还不是很好,但是随着技术的不断进步,相信只要我们不断学习,就能够更好的利用这个技术。希望本文能够对大家学习和使用 Regex 反向断言提供一些帮助。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64c8e5085ad90b6d0414fff9