利用正则实现数字千分位详解

7,363 阅读1分钟

费话不多说,先抛个答案

  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', 不满足匹配规则,结束匹配

至此,整个代码执行过程解析完毕,如有解释不当之处欢迎私信,或在评论区讨论