这个千分符的正则谁来帮我解释下

发布于 2022-09-07 11:26:17 字数 1647 浏览 10 评论 0

正则来源:
https://github.com/anran758/F...

/**
 * 千位分隔符
 *
 * @param {Number} num - 金额
 * @returns 返回格式化后的数字
 */
function numberWithCommas(num) {
  // 正则解释: 匹配到 \B(非单词边界)后, 后面要匹配到 (\d{3})+(?!\d)
  // (\d{3})+ 至少匹配到一次或多次三个数字
  // (?!\d) 同时后面不是数字的话, 就匹配.
  // 注意, 后面的(?=)那一段代码只是判断的规则, 匹配到后只替换掉\B
  // 这是一个很巧妙的方法 ..
  return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ',');
}

// '12,345'
'12345'.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

// '123,456e'
'123456e'.replace(/\B(?=(\d{3})+(?!\d))/g, ',');

这里用到了正则的几个形式如下(摘自百科):

\B
匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。

\d
匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
(?=pattern)
非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。

(?!pattern)
非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。

{n}
n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。

+
匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。

(pattern)
匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用$0…$9属性。要匹配圆括号字符,请使用“\(”或“\)”。

从我的理解 这里是要匹配\B,但是要求后面必须是3个数字且末尾不能是数字,那这样的话,只能匹配到 123456e这个字符串中的4前面那个位置才对
12345这个就不符合匹配,因为它不符合我理解的末尾不能是数字,不能匹配到才对,可是结果却匹配到了

正则对我来说还算一个比较新的块,所以求大佬指教

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

罪歌 2022-09-14 11:26:17

而且这个正则还有个bug
console.log(numberWithCommas(12345678912.1234))
12,345,678,912.1,234
小数后面不能正确处理,不知道哪位大神可以帮忙修正下

20180606更新:
自己这几天没事就关注下正则,整了个答案:

clipboard.png

/(B(?=(d{3})+(?!d)D))|(B(?<=D(d{3})+))/g

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文