ES8 的正则表达式扩展解析
正则表达式是前端开发中非常重要的一部分,ES8 中的正则表达式扩展提供了更为便捷和强大的操作方式。本文将详细解析 ES8 中的正则表达式扩展,包括正则表达式字面量中的新特性、RegExp.prototype
上的新方法以及字符串上的改进。
正则表达式字面量中的新特性
ES8 中引入了一些新的正则表达式字面量语法,使得正则表达式的书写更加简明易懂。
- 命名的捕获组
在 ES8 中,我们可以使用 ?<name>
的格式来为捕获组命名。例如,下面的正则表达式可以匹配一段以 aa 开头,以 bb 结尾的字符串,并且将 a 和 b 分别捕获到了两个命名的捕获组中。
const regex = /^(?<a>aa).*?(?<b>bb)$/; const str = 'aaxbbxbxbbxaaaabb'; const match = str.match(regex); console.log(match.groups); // { a: 'aa', b: 'bb' }
- 后行断言
传统的正则表达式只能匹配前面的内容,不能匹配后面的内容。但是在 ES8 中,我们可以使用后行断言来匹配后面的内容。后行断言的语法是 (?<=)
,例如:
const regex = /(?<=John\s)Doe/; const str = 'John Doe is not John Smith.'; const match = str.match(regex); console.log(match[0]); // Doe
上面的正则表达式匹配了 John 后面紧跟着的 Doe,但不包括 John 本身。
- 具名反向引用
在传统的正则表达式中,我们可以使用反向引用来引用之前的捕获组,例如 \1
表示第一个捕获组。在 ES8 中,我们可以为捕获组命名,并且可以使用 \<name>
的方式来引用命名的捕获组。例如:
const regex = /(?<quote>['"]).*?\<quote>/; const str = 'Hello "world"!'; const match = str.match(regex); console.log(match[0]); // "world"
上面的正则表达式匹配了双引号或单引号包裹的字符串,并且捕获了引号类型和字符串内容。在反向引用的时候,我们使用的是 \<quote>
而不是 \1
。
RegExp.prototype
上的新方法
ES8 在 RegExp.prototype
上也添加了新的方法,为正则表达式的使用带来了更多的灵活性。
RegExp.prototype.dotAll
在传统的正则表达式中,点号 .
只能匹配除了换行符以外的任意字符。但是现在我们可以使用 RegExp.prototype.dotAll
方法来匹配包括换行符在内的任意字符。例如:
const regex = /foo.bar/s; const str = 'foo\nbar'; const match = str.match(regex); console.log(match[0]); // foo\nbar
上面的正则表达式使用了 s
标记来启用点号匹配换行符。如果不使用 s
标记,foo.bar
将无法匹配包含换行符的字符串。
RegExp.prototype.sticky
RegExp.prototype.sticky
方法允许我们将正则表达式匹配的开始位置固定在上次匹配的结束位置。这对于对同一字符串多次进行正则匹配非常有用。例如:
const regex = /foo/y; const str = 'foofoofoo'; console.log(regex.test(str)); // true console.log(regex.test(str)); // true console.log(regex.test(str)); // true
上面的正则表达式使用 y
标记来启用黏性匹配。在进行连续的三次匹配时,每一次匹配都从上一次匹配结束的位置开始。
RegExp.prototype.flags
RegExp.prototype.flags
方法返回正则表达式的标记字符串。例如:
const regex = /foo/i; console.log(regex.flags); // i
上面的正则表达式使用了 i
标记来忽略大小写。
字符串上的改进
ES8 中对字符串的正则相关方法进行了一些扩展,包括 String.prototype.matchAll
和 String.prototype.replace
。
String.prototype.matchAll
String.prototype.matchAll
方法返回一个迭代器,该迭代器包含正则表达式匹配的所有结果(包括捕获组)。例如:
// javascriptcn.com 代码示例 const regex = /foo/g; const str = 'foofoofoo'; for (let match of str.matchAll(regex)) { console.log(match[0]); } // foo // foo // foo
上面的代码使用 matchAll
方法遍历了所有的 foo
。
String.prototype.replace
在传统的 String.prototype.replace
方法中,第二个参数可以是一个字符串或者用于替换的函数,但是当替换函数需要访问正则表达式的属性时,需要使用匿名函数。在 ES8 中,我们可以在替换函数中使用箭头函数,省略了匿名函数的麻烦。例如:
// javascriptcn.com 代码示例 const str = 'hello world'; const regex = /(hello)\s(world)/; const output = str.replace(regex, (match, group1, group2, index, input) => { return `${group1} ${group2.toUpperCase()} at index ${index} in ${input}`; }); console.log(output); // hello WORLD at index 0 in hello world
上面的代码使用了箭头函数来替换字符串,并且达到了更加简洁的效果。
总结
ES8 中的正则表达式扩展为我们提供了更加便捷和强大的操作方式。我们可以使用命名的捕获组和具名反向引用来改善传统的正则表达式,在 RegExp.prototype
上使用新的方法来增加正则的灵活性,在字符串上使用新的方法来减少书写的复杂度。对于前端开发者而言,学习 ES8 中的正则表达式扩展无疑是非常有意义的。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/653870917d4982a6eb13b78c