费话不多说,先抛个答案
const reg = /(\d)(?=(?:\d{3})+$)/g;
我们先介绍一下用到的一些 “特殊字符”
(x)匹配x并记住它,后续可通过$1,$2,...或者\1,\2,...来使用x(?=y)匹配x当且仅当x后面跟着y时,但是y不是匹配结果的一部分(?:x)匹配x, 这里不会被记住, 跟(x)做对比记忆+贪婪匹配,匹配一个或多个$匹配输入结束。如果多行标示被设置为 true,那么也匹配换行符前的位置。例如,/t$/并不会匹配 "eater" 中的 't',但是会匹配 "eat" 中的 't'。
接下来我们看看这个正则会匹配哪些内容?
- '123' 不匹配
- '1234' 匹配 1 次,匹配结果为 '1'
- '1234567' 匹配 2 次,匹配结果为 '1', '4'
接下来解析一下执行过程
const reg = /(\d)(?=(?:\d{3})+$)/g;
const str = '1234567';
str.replace(reg, '$1,')
正则翻译: 查找数字后面有多组三个数字,且以三个数字为结尾
第一次匹配:我们从后往前看,'567', '234', '1' 匹配结果为 '1' $1 代表匹配结果 '1', 并在此后追加 ',' 此时结果为 '1,234567'
第二次匹配:从 '1' 后面开始,因为我们此前只匹配了一个字符串 '1',进入匹配的字符串为 '234567',从这个字符串中寻找以“三个数字”为结尾,且前面有一位数字的字符串,很容易找到 '4567',此时匹配结果为 '4' 结果为 '1,234,567'
第三次匹配: 从 '4' 后面开始,进入匹配的字符串为 '567', 不满足匹配规则,结束匹配
至此,整个代码执行过程解析完毕,如有解释不当之处欢迎私信,或在评论区讨论