在 ECMAScript 2018(ES9)中,正则表达式得到了一些新的特性,其中最有趣的一个特性就是命名捕获组(Named Capture Groups)。命名捕获组是一种更加灵活和可读性更高的正则表达式语法,可以让你使用自定义的名称来捕获匹配的子字符串。在本文中,我们将深入探讨命名捕获组的用法和示例。
命名捕获组的语法
在正则表达式中,使用圆括号来捕获匹配的子字符串,例如:
const regex = /(\d{4})-(\d{2})-(\d{2})/; const match = regex.exec('2019-12-25'); console.log(match[0]); // "2019-12-25" console.log(match[1]); // "2019" console.log(match[2]); // "12" console.log(match[3]); // "25"
在上面的例子中,我们使用正则表达式 /(\d{4})-(\d{2})-(\d{2})/
来匹配日期字符串,其中每个圆括号表示一个捕获组。当我们调用 regex.exec
方法时,它会返回一个数组,其中第一个元素是匹配的整个字符串,后面的元素是每个捕获组匹配的子字符串。
命名捕获组的语法与普通的捕获组类似,只不过在圆括号内部使用 ?<name>
来指定捕获组的名称,例如:
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const match = regex.exec('2019-12-25'); console.log(match.groups.year); // "2019" console.log(match.groups.month); // "12" console.log(match.groups.day); // "25"
在上面的例子中,我们使用正则表达式 /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
来匹配日期字符串,其中 ?<name>
表示命名捕获组。当我们调用 regex.exec
方法时,它会返回一个数组,其中第一个元素是匹配的整个字符串,而 match.groups
则是一个对象,包含了每个命名捕获组匹配的子字符串。
命名捕获组的优势
使用命名捕获组有以下几个优势:
- 更加可读性高:命名捕获组可以使用自定义的名称来表示捕获的子字符串,这样可以让正则表达式更加易于理解和维护。
- 更加灵活性高:命名捕获组可以在正则表达式中引用,这样就可以在后续的匹配中使用捕获的子字符串。例如:
const regex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/; const str = '2019-12-25'; const newStr = str.replace(regex, '$<month>/$<day>/$<year>'); console.log(newStr); // "12/25/2019"
在上面的例子中,我们使用正则表达式 /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/
来匹配日期字符串,并在 replace
方法中使用 $<name>
来引用命名捕获组。这样就可以将日期字符串中的年、月、日分别提取出来,然后按照月/日/年的格式重新排列。
命名捕获组的使用示例
下面是一些命名捕获组的使用示例:
1. 匹配邮箱地址
const regex = /(?<username>[a-zA-Z0-9._%+-]+)@(?<domain>[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/; const email = 'test@example.com'; const match = regex.exec(email); console.log(match.groups.username); // "test" console.log(match.groups.domain); // "example.com"
在上面的例子中,我们使用正则表达式 /(?<username>[a-zA-Z0-9._%+-]+)@(?<domain>[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})/
来匹配邮箱地址,其中 ?<username>
和 ?<domain>
表示命名捕获组。当我们调用 regex.exec
方法时,它会返回一个数组,其中第一个元素是匹配的整个字符串,而 match.groups
则是一个对象,包含了每个命名捕获组匹配的子字符串。
2. 匹配 CSS 颜色值
const regex = /#(?<red>[0-9a-fA-F]{2})(?<green>[0-9a-fA-F]{2})(?<blue>[0-9a-fA-F]{2})/; const color = '#ff0000'; const match = regex.exec(color); console.log(match.groups.red); // "ff" console.log(match.groups.green); // "00" console.log(match.groups.blue); // "00"
在上面的例子中,我们使用正则表达式 /#(?<red>[0-9a-fA-F]{2})(?<green>[0-9a-fA-F]{2})(?<blue>[0-9a-fA-F]{2})/
来匹配 CSS 颜色值,其中 ?<red>
、?<green>
和 ?<blue>
表示命名捕获组。当我们调用 regex.exec
方法时,它会返回一个数组,其中第一个元素是匹配的整个字符串,而 match.groups
则是一个对象,包含了每个命名捕获组匹配的子字符串。
3. 匹配 URL 中的参数
-- -------------------- ---- ------- ----- ----- - ------------------- ----- --- - ------------------------------------------------------------- ----- ----- - ---------------- ----- ------ - -------------------------------- ----- -- - ----- ----- ------ - ---------------- -------- - ------ ------ ---- -- ---- -------------------- -- --- ------------- ----- --------
在上面的例子中,我们使用正则表达式 /(?<=\?).*(?=#|$)/
来匹配 URL 中的参数部分,其中 (?<=\?)
表示零宽度正回顾后发断言,匹配 ?
符号前面的内容,.*
表示匹配任意字符,(?=#|$)
表示零宽度正向前瞻断言,匹配 #
符号或字符串结尾后面的内容。当我们调用 regex.exec
方法时,它会返回一个数组,其中第一个元素是匹配的整个字符串。
接着,我们使用 split
方法将参数字符串按照 &
符号分割成数组,然后使用 reduce
方法将数组转换成对象。这样就可以方便地获取 URL 中的参数了。
结论
命名捕获组是 ECMAScript 2018(ES9)中一个非常有用的特性,它可以让正则表达式更加灵活和可读性更高。在实际开发中,我们可以使用命名捕获组来匹配和处理各种复杂的字符串。希望本文对你有所帮助,谢谢阅读!
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/675f8b62e49b4d0716260bf0