正则:将一串数字的每3个就用逗号分开的问题

'12334565632'.replace(/(\d)(?=(\d{3})+$)/g, "$1,");
//结果:"12,334,565,632"

上边这个是网上找的,是可以实现的,但是和我理解的不一样,我说下我是怎么想的,大家帮我指正下,谢谢。
1.(?=(\d{3})+$)/g 这里用了一个零宽断言,我认为(\d{3})后边这个+是说出现1次或更多次的意思,那么如果我将前边的字符串换成'2'的时候我发现也匹配成功了,按理说他没有匹配到3个数字啊!为什么还是成功了呢??

2.这个$1匹配的应该是表达式(\d)这个啊,这个不是1个数字吗,为什么显示结果$1匹配的确是3位呢??

求大神解答··

阅读 15.9k
9 个回答

网上这个方法用的是 零宽度正预测先行断言,它断言匹配的自身出现的位置d的后面能跟着匹配到1个或者n个3位数且刚好到结尾$
1.那么如果我将前边的字符串换成'2'的时候我发现也匹配成功了,不管你换的是字符串还是正则表达式,应该都是不成功的。
2.$1匹配的就是表达式(d)这个。你可以把全局g去掉看一下:

'12334565632'.replace(/(\d)(?=(\d{3})+$)/, "$1,"); //"12,334565632"

题中分别匹配的是str[1],str[4],str[7] ,并在后面加上','

/(d)(?=(d{3})+$)/g: 全局(即多次)匹配一个数字, 这个数字后面接着N(N>=1)个三位数(三位数被当做一个整体体看待)后字符串结束.

这个匹配过程, 大概可以这么想:

var re = /(\d)(?=((\d{3})+)$)/g;
var str = '12334565632';
var lookup = '';
var match;
while(match = re.exec(str)) {
    console.log('匹配数字'+ match[1] + ', 该数字后面跟着' + match[2].length/3 + '次三位数, 因此在' + match[1] + '的后面加上一个","');
}

谢邀!
/(\d)(?=(\d{3})+$)/g , 这个正则表达式我是这么理解的:
先理解一个要点:/(\d)(?=(\d{3})+$)/g
红色的 \d$ 之间,数字字符的个数是 3 的整数倍。

然后,把这个数字字符捕获到分组中,在它后边加个逗号“,”。
效果如下:
'12334565632'
替换后:
'12,334,565,632'

零宽断言,是为了保证后面的字符不被消耗掉,这样可以多次匹配。

为啥不是

'12334565632'.replace(/(\d{3})/g, "$1,"); //"123,345,656,32"

问题一:

(\d{3})+$ 的意思是连续匹配 3 个数字,且最后一次匹配以 3 个数字结尾。如果将数字变成 2,那么就是连续匹配 2 个数字且最后一次匹配也是 2 个数字,就像这样 "1,23,34,56,56,32"

问题二:

$1 并不是 1 ,因为 1 并不符合条件(?=(\d{3})+$),它要求一个数字(\d)后面的数字的个数是 3 的倍数,只要满足这种条件,(\d) 才能匹配成功,才能让 $1 反向引用。“12334565632” 这个例子中,只有第二,第五,第八个数字满足条件

第一问你说的换成2是指把{3}换成{2}吗? 这样最后结果只会是"1,23,34,56,56,32"

第二问我的理解是$1指的是匹配出来的项中符合第一个小括号的内容,匹配的项有"5632","4565632","2334565632",红色部分就是符合第一个小括号的,然后在这几个数的后面添加逗号。

你既然知道这个是零宽断言,那么应该就没太多疑问了啊?
这个零宽断言,第一层意思是
(?=(d{3})+$)
这个.从右向左匹配{3} 即3个数字,然后断言为真,这时
向左再匹配一个数字(d)
匹配到之后 执行replace "$1," 即将这个匹配数字替换为这个数字和后面追加逗号了.
然后呢, /g 全部替换,因此继续走零宽断言. 因为是零宽的,所以不算长度,那么继续刚才的过程.
匹配三个数字,然后再向前查一个,替换为找到的数字+逗号.
直到零宽断言返回false停止.

/(\d)(?=(\d{3})+$)/匹配的是一个数字,即(\d),
它后面的字符串必须是三的倍数,这个表达就是(?=(\d{3})+$)
$1,表示在第一个分组表达式匹配的字符后面加,,这里其实只有一个(\d),问号后面的可以看成它的定语。
/(\d)(?=(\d{3})+$)/g因为多了g,表示全局(global)匹配
这个表达式通俗来说是

要找到所有的单个字符,这些字符的后面跟随的字符的个数必须是3的倍数,并在符合条件的单个字符后面添加,

知识点:(?=exp) 零宽度正预测先行断言

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