ES9(ECMAScript 2018)中的正则表达式 named capture groups

阅读时长 7 分钟读完

正则表达式是前端开发中不可或缺的工具之一。在 ECMAScript 2018 中,引入了一项新的特性——“命名捕获组(named capture groups)”,在处理正则表达式匹配时可以大大提高代码的可读性和可维护性。

在此我们来详细地探讨这个新特性,并给出一些实用的示例代码,帮助大家更好地理解和应用它。

什么是命名捕获组

我们知道,在正则表达式中,使用括号(())将某一部分子表达式括起来,作为一个“捕获组(capture group)”,它能够捕获和匹配符合条件的字符串,方便后续处理。而在 ECMAScript 2018 中,我们可以给这些捕获组起一个名字,方便在后续代码中直接引用这个组,而不必使用索引。

例如,下面是一个匹配日期的正则表达式,其中包含了三个捕获组:

在上面的代码中,我们使用括号将年、月、日三个部分括起来,称为“捕获组”,然后使用数组的解构语法,将这三个捕获组分别赋值给了变量yearmonthday

然而,若是你的正则表达式更为复杂,包含多个捕获组,那么就会出现这样的情况:

在上面这个例子中,我们需要根据一大堆数字和字母的组合,手动去分配各个捕获组的值,使得代码变得冗长而不易读。

这时,命名捕获组就可以为我们解决这个问题。我们只需在括号内给捕获组起一个名字,就可以在解构语法中直接使用这个名字,而不必再去使用索引。

可以看到,上面的代码使用了ES9中的新特性——“命名捕获组”,通过在括号内使用(?<名字>语法为捕获组命名,这使得后续的解构语法变得非常简单和直观,易于理解和维护。同时,我们还可以通过groups属性,得到命名捕获组的值,同样的变量名和正则表达式中引用的名字保持一致,这使得代码语义更加清晰,易于阅读。

命名捕获组的语法

命名捕获组使用(?<name>语法来定义。其中,name是捕获组的名字,可以是任何合法的标识符。你可以像下面这样定义一个命名捕获组:

当然,命名捕获组还支持使用数字命名(如(?<1>\d{4}))和混合命名(如(?<1st_year>\d{4}))。

命名捕获组和未命名捕获组的区别

使用命名捕获组的主要优势是,我们可以使用捕获组的名字直接引用一个组,而不是使用默认的索引。

如果你在正则表达式中使用了未命名的捕获组,那么它们可以通过索引在后续代码中使用。例如,在下面的例子中,我们使用了未命名的(或者说默认的)捕获组,然后使用了一个索引来直接引用这个组:

不过,在后续代码中使用索引将导致代码不够明确,并且容易出错。而通过命名捕获组,我们可以大幅提高代码的可读性和可维护性,甚至可以在复杂的正则表达式中方便地引用不同的捕获组。

示例代码

让我们看一下几个实用的使用命名捕获组的示例代码:

抽取链接中的主机名

在上面的例子中,我们使用了命名捕获组(?<host>匹配链接中的主机名。这个正则表达式还支持捕获链接中的协议名、主机端口和路径,但由于我们只需要主机名,所以我们只引用了捕获组host

替换字符串中的相邻字母

在上面的例子中,我们使用了命名捕获组(?<a>(?<b>同时捕获两个相邻的字母,然后使用$2$1实现了字母交换的效果。

抽取 log 数据

-- -------------------- ---- -------
----- --- - -------------------------------------------------------------------------------------------------------------------------------------------
----- --- - ----------- -------- ------ ------ --------
----- ----- - ---------------
--------------------------
-- - ----- -------
--   ------ -----
--   ---- -----
--   ----- -----
--   ------- -----
--   ------- -----
--   ------ -------
--   -------- ------- ------- -

在上面的例子中,我们使用了一条复杂的正则表达式,捕获了日志中的时间、级别和信息。使用命名捕获组(?<year>等,可以方便地在后续代码中引用捕获到的数据。这使得代码的可读性和可维护性均得到了提升。

总结

使用命名捕获组是 ECMAScript 2018 带来的一个非常实用的新特性。它可以大幅提高代码的可读性和可维护性,并且方便后续代码中直接引用捕获到的数据,从而避免使用索引带来的风险和不方便。

在使用正则表达式时,我们应该尽可能使用命名捕获组,并结合具体的场景,使用其提供的更多高级特性来优化自己的代码。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/649e457248841e9894acdcae

纠错
反馈