Javascript中正则表达式$1探讨

如何将一串数字格式化为逗号表千分位。找到一种使用正则表达的方法,一直不太明白。花了点时间将匹配过程记录下来。由于理解能力较差,其中的"$1"着实烧脑了一阵子。有些结论是我测试的结果,可能有些偏差,请大家斧正。

我们先从例子入手:将“1234567890”输出为“1,234,567,890"
javascript代码:

let strTemp = '1234567890'.replace(/(\d)(?=(\d{3})+$)/g, '$1,')

大家可以试试,看到了吧,就是这么简单,下面分解一下为什么会得到正确的结果。正则表达式为
(\d)(?=(\d{3})+$)
里面使用到了下面的元素:

描述表达式
捕获模式(表达式)
正向预查模式(?=表达式)
匹配 n次{n}
匹配 1 次或多次+
最少 m 次,最多 n 次匹配{m,n}
字符串结尾$
匹配数字\d

分解一下:
(\d{3})+$,是从结尾重复匹配连续的3个数字

在此例中等价于 (\d{3}){1,3}$
1234567890 输出 1234567890,相当于234 567 890这三组数字一起输出,如果改成

(\d{3}){1,1}$
1234567890 输出 1234567890

(\d{3}){1,2}$
1234567890 输出 1234567890

下一步,重点来了,使用正向预查模式(?=表达式),输出表达式”(\d{3})+$“之前的部分

(?=(\d{3})+$)

1234567890 输出三个空位置,用"x"表示 1x234x567x890
现在懞圈了吧,为什么输出三个x呢?
因为”+"为匹配 1 次或多次,而(?=表达式)匹配一次就输出一次,
第一次匹配"890"就输出“x890"前的x
第二次匹配"567890"就输出“x567890"前的x
第三次匹配"234567890"就输出“x234567890"前的x。
没有第四次,因为再向前匹配只有一个数字1,条件不满足了。

好了,下面只需将所有"x"代替为",“就行了。可是"x"仅仅是几个空位置,可视化不强,所以再做一点变形加上”(\d)“,表示为匹配正向预查结果之前的一个数字,分别为1,4,7
(\d)(?=(\d{3})+$)
1234567890 输出 1234567890
最后用上面的JS语句将"1”,“4”,“7"替换为"1,”,“4,”,“7,”,就可输出正确结果。

到现在为止没有跟"$1"扯上任何关系,各位不慌,下面继续展开。

let strTemp = '1234567890'.replace(/(\d)(?=(\d{3})+$)/g, '$1,')

上面的”$1“是个什么鬼呢,它表示捕获模式下从左向右第一个(表达式)的匹配结果,此例中”$1“是(\d),这没什么可说的,我要说的是下面这个表达式中”$1“表示什么

(?=(\d{3})+$)
经过我测试,正向预查模式”(?=表达式)“的输出不是”$1“,

所以就是它了
(\d{3})+$
但是问题来了,你不是说这个会输出三个,分别是”890“,”567890“,”234567890“,到底是哪一个?
经过测试它只输出第一次匹配,也就是”890“
结论是在匹配 1 次或多次"+“表达式中,虽然结果只是输出最长的匹配,”$1"根据匹配方向不同,结果也不同
(\d{3})+ 或 ^(\d{3})+
1234567890 输出 1234567890,“$1"保留最后一次匹配结果"789”

(\d{3})+$
1234567890 输出 1234567890,“$1"保留第一次匹配结果"890”

而(\d{3})就比较奇怪了,"$1"似乎有三个结果”123“,”456“,”789“,目前还未有合理的解释。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值