正则表达式`replace`的问题

JS语言精粹中有如下代码:

'(555)666-1212'.replace(/\((\d{3})\)/g, '$1-');
// 555-666-1212

按照定义$1-是替换捕获组1的内容为捕获组1-, 那么问题来了: 捕获组1不应该是555而不是(555)? 为什么两个括号也被替换掉了?

'(555)666-1212'.match(/\((\d{3})\)/)
//["(555)", "555"]
阅读 3.1k
5 个回答

一步一步来:

String.prototype.replace.call('223322', /22(\d{2})22/, 'replaced!')
//"replaced!"

String.prototype.replace是会搜寻整个正则表达式/22(d{2})22/的内容并用'replaced!'字符串来替换, 不管正则内有没有分组;

String.prototype.replace.call('223322', /22(\d{2})22/, '$1')
//"33"

'$1'则指代捕获组1的内容, 在这里就是'33'. 因此整个正则所匹配的内容会被替换成为'$1'的内容.

具体到这里, /((d{3}))/g匹配的是'(555)', 捕获组1捕获到的则是'555', 因此'(555)'会被替换为'555' + '-'.

匹配的确实是555,所以换的结果不是(555)-666-1212,你再想想。。

数组的第 0 个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本(也就是用小括号包起来的),所以$1是替换(555),$2才是替换555。

你这意思就是把(555)替换成555-

楼主说的这个,前面的(/((d{3}))/g是把(555)变成555),后面的再用('$1-')加上"-"

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进