JS 正则中的命名捕获分组
假设你在一段陌生的代码中看到这样一个函数:
function toLocalDate(date) {
return date.replace(/(\d{2})-(\d{2})-(\d{4})/, "$2-$1-$3")
}
单看这个函数你能知道它是想把“日-月-年”替换成“月-日-年”,还是反过来?匿名捕获分组没法做到这一点,那就该命名捕获分组上场了:
function toLocalDate(date){
return date.replace(/(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/, "$<day>-$<month>-$<year>")
}
俗话说的好,“一个好的变量名赛过一行注释”,命名捕获分组很大的一个作用就是它能起到注释的作用。
另外,命名捕获分组还有一个好处,那就是假如你在修改一个正则时,在已有分组的左边引入了新的分组,那么你还得记得更新已有的反向引用的数字。比如将 (foo)\1 改成了 (bar)(foo)\1,那你得把原来的 \1 改成 \2,replace() 方法的第二个参数里的 $1 也同样得改,用命名分组不会有这个问题。
语法
命名捕获分组自身的语法是 (?<name>...),比普通的分组多了一个 ?<name> 字样,其中 name 的起法就和你平时起变量名一样即可(不过在这里关键字也可用)。
反向引用一个命名分组的语法是 \k<name>,注意命名分组同样可以通过数字索引来反向引用,比如:
/(?<foo>a)\k<foo>\1/.test("aaa") // true
在 replace() 方法的替换字符串中反向引用是用 $<name>:
"abc".replace(/(?<foo>a)/, "$<foo>-") // "a-bc",同样 $1 仍然可用
总结一下就是,和命名分组相关的有三种语法,分别是 ?<name>、\k<name>、$<name>,相同点是都用尖括号包裹着分组名。
在 API 中的使用
在 exec() 和 match() 中的使用:
const groups = "04-25-2017".match(/(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/).groups // {month: "04", day: "25", year: "2017"} const {day, month, year} = groups
exec() 和 match() 方法返回的匹配结果数组上多了一个 groups 属性,里面存放着每个命名分组的名称以及它们匹配到的值,利用 ES6 的解构语法,可以方便的提取出想要的字段。注意这个 groups 属性只有在当前正则里至少存在一个命名分组的前提下才会存在,比如:
/(\d{2})-(\d{2})-(\d{4})/.exec("04-25-2017").groups // undefined,因为没有命名分组
在 replace(/.../, replacement) 中的使用:
replacement 是字符串的情况上面已经举过例子了,这里主要讲它是函数的情况:
"04-25-2017".replace(/(?<month>\d{2})-(?<day>\d{2})-(?<year>\d{4})/, (...args) => {
const groups = args.slice(-1)[0]
const {day, month, year} = groups
return `${day}-${month}-${year}`
}) // "25-04-2017"
也就是说,在实参列表的最末尾,多传了一个 groups 对象。同样,如果正则里没有命名分组,这个参数不会存在。
异常情况
分组名不能有重复项:
/(?<foo>a)(?<foo>b)/ // SyntaxError: Duplicate capture group name
反向引用一个不存在的分组名:
/\k<foo>/u // SyntaxError: Invalid named capture referenced /\k<foo>/.test("k<foo>") // true, 非 Unicode 下为了向后兼容,k 前面的 \ 会被丢弃
在 reaplce() 方法的替换字符串中引用一个不存在的分组:
"abc".replace(/(?<foo>.*)/, "$<bar>") // SyntaxError: Invalid replacement string "abc".replace(/(.*)/, "$<bar>") // "$<bar>",不包含命名分组时会向后兼容
总结
V8 目前已经完全实现了命名捕获分组的提案 https://tc39.github.io/proposal-regexp-named-groups/。
命名分组虽然带来了一些好处,但我个人觉得,正则越长越难读懂,尤其增加的长度是一堆小括号和尖括号。在可读性上,命名分组也许会起到反作用,尤其对正则苦手来说。
JS 正则中的命名捕获分组的更多相关文章
- Python中正则匹配使用findall,捕获分组(xxx)和非捕获分组(?:xxx)的差异
转自:https://blog.csdn.net/qq_42739440/article/details/81117919 下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑. 例 ...
- JS 正则中环视(断言)应用 -- 数字千分符
介绍一下顺序环视 (?=...) 和逆序环视 (?<=...) 方便不想看长文的人,如果在支持 ES2018 的环境中整数可以这样使用: String(12345678).replace(/(? ...
- 分享一下js正则中惰性与贪婪
首先引入一个介绍比较详细的网站 http://www.cnblogs.com/yuaima/p/5258513.html http://www.jb51.net/article/31491.htm 接 ...
- js正则中的贪婪和非贪婪模式问题总结
var b="abeeee:eeeee:eeeeeab"; console.log(b.match(/e+\:e+/g));//["eeee:eeeee"]贪婪 ...
- js正则及常用方法函数总结
正则表达式作为一种匹配处理字符串的利器在很多语言中都得到了广泛实现和应用,web开发本质上是处理字符串(服务端接受请求处理后拼接字符串作为响应,这在早期的CGI编程中最明显,然后客户端解析字符串进行渲 ...
- js 正则常用函数 会正则得永生
正则表达式作为一种匹配处理字符串的利器在很多语言中都得到了广泛实现和应用,web开发本质上是处理字符串(服务端接受请求处理后拼接字符串作为响应,这在早期的CGI编程中最明显,然后客户端解析字符串进行渲 ...
- js正则基础总结和工作中常用验证规则
知识是需要系统的.就像js正则用了那么多次,却还是浑浑噩噩,迫切需要来一次整理,那么来吧! 基本知识 元字符 \d 匹配数字等于[0-9] \w 匹配字母.数字.下划线.中文 \s 匹配任意空白字符 ...
- Django---路由系统,URLconf的配置,正则表达式的说明(位置参数),分组命名(捕获关键字参数),传递额外的参数给视图,命名url和url的反向解析,url名称空间
Django---路由系统,URLconf的配置,正则表达式的说明(位置参数),分组命名(捕获关键字参数),传递额外的参数给视图,命名url和url的反向解析,url名称空间 一丶URLconf配置 ...
- js正则实现从一段复杂html代码字符串中匹配并处理特定信息
js正则实现从一段复杂html代码字符串中匹配并处理特定信息 问题: 现在要从一个复杂的html代码字符串(包含各种html标签,数字.中文等信息)中找到某一段特别的信息(被一对“|”包裹着),并对他 ...
随机推荐
- 超哥笔记--linux准备知识(1)
一 岗位 前端小姐姐 python后端大神 测试工程师 测试+python 测试开发 运维工程师(背锅侠) -安全运维 -linux系统管理员 -桌面运维(helpdesk) -IDC机房运维(服务器 ...
- Ambari与Kerberos 集成
Kerberos 介绍 Kerberos 是一个网络认证的框架协议,其设计的初衷便是通过密钥系统为 Client 和 Server 应用程序之间提供强大的认证服务.在使用 Kerberos 认证的集群 ...
- docker 常用命令和常用容器启动
docker:systemctl start docker # docker 启动systemctl stop docker # docker 停止systemctl restart docker # ...
- 在Mac OS X中完善PHP环境:memcache、mcrypt、igbinary
本文环境: Mac OS X 10.8.5 Xcode 5.0 Mac OS X升级到10.8.5之后,内置的Apache升级到2.2.24,PHP升级到了5.3.26.本文以此环境为基础. 本文简介 ...
- 网络虚拟化基础一:linux名称空间Namespaces
一 介绍 如果把linux操作系统比作一个大房子,那命名空间指的就是这个房子中的一个个房间,住在每个房间里的人都自以为独享了整个房子的资源,但其实大家仅仅只是在共享的基础之上互相隔离,共享指的是共享全 ...
- 2017-8-2新开了一个ABP交流的QQ群(291304962 ),欢迎加入
因为ABP架构设计交流群人数一直爆满,很多想交流ABP的朋友无法加进群里, 刚新建了一个QQ群,群号291304962(ABP架构设计交流群3),欢迎对ABP感兴趣的朋友加入. 欢迎加QQ群: ABP ...
- 拜托!面试请不要再问我Spring Cloud底层原理
概述 毫无疑问,Spring Cloud是目前微服务架构领域的翘楚,无数的书籍博客都在讲解这个技术.不过大多数讲解还停留在对Spring Cloud功能使用的层面,其底层的很多原理,很多人可能并不知晓 ...
- python部署lvs
lvs-dr-rr import paramiko vip = '192.168.254.250' ds = '192.168.254.17' rs1 = '192.168.254.37' rs2 = ...
- codeforces#1136 C. Nastya Is Transposing Matrices(找规律)
题意:给出两个n*m的矩阵,每次操作可以让一个正方形矩阵行列交换.问,在无限次操作下,第一个矩阵能否变成第二个矩阵 分析:先把操作限定在2*2的矩阵中.这样对角线上的元素就可以随意交换.也就是说,如果 ...
- 番外篇-AppService服务
一. public async Task<ListResultDto<ArchitectureDto>> GetArchitecture() { var architectur ...