正则格式化金额数字

avatarplhDigital nomad

description

1234578901 => '1,234,578,901'

零宽断言 + 贪婪匹配 + 匹配结尾

"1234578901".replace(/(?=(\d{3})+$)/g,',')     // 1,234,578,901
  • (?=exp)+ 匹配开头匹配以3个字符串结尾的空节点, 后面追加了+,等效于{1,n},代表了匹配1到n次以零宽断言(?=exp)开头的空节点
  • /g 全局匹配
  • $从尾部开始匹配,
  • ',' 将匹配到的空节点 替换成","

缺陷1

首字母即使没有数字,也会被匹配,

'123456765434343'.replace(/(?=(\d{3})+$)/g,',')     // ",123,456,765,434,343"

零宽断言 - 匹配 以xxxx开头的空节点

同样是让他做开头匹配,但又不匹配它本身,这次我们在头部设置必须匹配+个数字,也就是{1,n}个数字

'123456765434343'.replace(/(?<=\d+)(?=(\d{3})+$)/g,',')     // "123,456,765,434,343"
  • (?<=exp) 匹配 以xxxx开头的节点因为后面没有追加{1,2},+,., 所以只匹配一次

关键问题

为什么会从后面开始匹配? 这就是$的作用了,他就代表了从尾巴开始匹配 而 ^则代表从头部开始匹配...

(?=exp) - 零宽度正预测先行断言

它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。

(?<=exp) - 零宽度正回顾后发断言

它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

缺陷2

我再一次给自己加戏.....

有小数的数字我该如何匹配

'123456765434343.12'.replace(/(?<=\d+)(?=(\d{3})+$)/g,',')     // "123456765434343.12"

不纠结,直接用, 可 parse 任意数字.

Number(amount).toLocaleString()

Tools

online regexp