uncategorized

插入数字千位分隔符 -- 从一个技巧复习js正则表达式

来一起复习一下正则表达式

题目

将一个整数串转为每千位逗号分隔的模式,就像表示金额的时候那样, 123456789 -> 123,456,789

一种直观的解法是从最后一位循环处理,每遇到三位就插入一个逗号,这是基础套路,稳的一批,我们在此就不做介绍

像这种带有明显模式(pattern)的场景,我们也可以用正则来进行处理

使用正则的一种做法是,找到每三个字符之间的那个位置(是个空字符串),然后使用 replace api 对所有出现的位置替换成逗号

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

这段正则的核心是,我们使用了一个先行断言(?=xxx), 先行断言表示我们要匹配的位置后面跟着xxx才符合匹配要求,而不是描述我们要匹配的内容本身是什么样的,有点像编程语言里的if条件

在上述我们的例子里,xxx 是 \d{3}+$, 翻译过来就是:从尾部开始数,包含1-n个三个数字的组合, 所以我们最终匹配到的位置就是从尾部开始的第3个数字前、第6个数字前、第9个数字前……

再配合replace api

"123456789".replace(/(?=(\d{3})+$)/g, () => ",")

over and out

一个正则开发辅助利器

工欲善其事必先利其器,RegExr 就是一个开发正则很好的工具箱,集正则验证、分解、解释、reference 于一身

Anyway, give it a shot

复习正则

正则表达式乍一看乱糟糟的一堆乱码,但按照正则表达式的字符类型来拆分梳理也容易理解

正则表达式最常用的几个组成部分: 断言, 字符类, 组和范围, 量词

断言

断言用来标明一些特定位置下的特定条件,类似于编程语言里的 if 条件, 如 /^123/ 其中的 ^断言就是为了标明,我们将匹配的123一定是开头的,其他的不算

表示 含义 备注
^ 边界类断言
$ 边界类断言
\b 边界类断言
\B 边界类断言
X(?=Y)
X(?!Y)
X(?<=Y)
X(?<!Y)

字符类

字符类与直接使用字面量一样,是用来匹配字符本身的,但与直接使用字面量不同,是用来标明一类字符的,如上例中的/^123/中,123标明我们要匹配的内容等于123,如果我们需要匹配的是任意一个数字呢,总不能或运算穷举所有可能的组合吧 /1|2|3|4.../, 这时我们就可以用一个 /\d/ 来标明匹配所有的一位数字,即0-9

表示 含义 备注
\d 所有数字 同[0-9]
\D 所有非数字 同[^0-9]
\w 所有字母数字和下划线 同[a-zA-Z0-9_]
\W 除了字母数字下划线外的字符 同[^a-zA-Z0-9_]
\s 匹配单个空白字符 常见空白字符,空格 / tab / 换行符
\S 匹配单个空白字符

在正则中,常用大写转义字符表达与小写转义字符相反的含义,如 \d 和 \D

组和范围

表示 含义 备注
x|y
[xyz] [a-c]
[^xyz][^a-c]
(x)
x(?=y) 先行断言
(?<=y)x 后行断言
x(?!y) 正向否定查找
(?<!y)x 反向否定查找

量词

表示 含义 备注
x*
x+
x?
x{n}
x{n,}
x{n,m}

◉ End.


参考资料:

  1. Regular expressions

如博文有叙述不妥以及不准确的地方, 望各位看客不吝赐教, 感谢.

Share