一、正则表达式特殊字符表
二、正则表达式模式
1. 简单模式
直接匹配对应字符: /abc/,精准匹配,字符间不可出现空格、标点符号等字符。
const str = 'abc,abc,ab,c'
console.log(str.match(/abc/g)) //['abc', 'abc']
2. 使用特殊字符
匹配 不确定的字符串 。更多特殊字符含义请查阅MDN相关文档。下面简单列举常用字符及千位符用到的特殊字符的含义
字符 | 含义 |
\ | 1. \后是非特殊字符 如字母b是非特殊字符,加上\后变成\b,此时成为特殊字符,具有特殊含义 2. \后是特殊字符,则为 转义 字符串,用作使用特殊字符的字面值 特殊字符:\b \B \cM \s \d \D \f \n \r \s \t \v \w \W \n(这里n是数字) \0 \xhh \uhhhh ...具体含义请参考文档 \加特殊字符\b,变成\\b,则变成普通字面量b \加特殊字符\,变成\\,转成普通字面量\ 这里需要注意,使用 构造函数 和 字符串文字 一起使用 的时候,反斜杠 \ 是字符串文字中的转义,我的理解是构造函数中要多加一个反斜杠,如/[a-z]\s/i和new RegExp("[a-z]\\s", "i") 含义相同 |
^ | 匹配输入的开始。如果多行标志被设置为 true,那么也匹配换行符后紧跟的位置。 |
$ | 匹配输入的结束。如果多行标志被设置为 true,那么也匹配换行符前的位置。 |
* | 匹配前一个表达式 0 次或多次。等价于 {0,} 。 |
+ | 匹配前面一个表达式 1 次或者多次。等价于 {1,} 。 |
? | 匹配前面一个表达式 0 次或者 1 次。等价于 如果紧跟在任何量词 *、 +、? 或 {} 的后面,将会使量词变为非贪婪(匹配尽量少的字符),和缺省使用的贪婪模式(匹配尽可能多的字符)正好相反。例如,对 "123abc" 使用 |
. | (小数点)默认匹配除换行符之外的任何单个字符。 |
(?:x) | 匹配 x 但 不记住匹配项,也叫 非捕获括号,定义与正则表达式运算符一起使用的子表达式,这里可以理解的是,x 是一个 字符串,后续的特殊字符将作用在 x 这一整个字符串上,文档解释: |
x(?=y) | 先行断言,匹配 x 后紧跟着 y 的字符串,这里的 y 并不在匹配的结果里,相当于是一种条件,只匹配后面紧跟着 y 的字符串 x |
\b | 匹配一个词的边界。如 /\bo/ 匹配以 o 为边界的 o,需要注意的是,\b不能在中间,因为只要在中间就代表两边有值,就不可能是边界 |
[\b] | 匹配一个退格 (U+0008)。(不要和\b混淆了。) |
\d | 匹配一个数字。 等价于 [0-9] 。 |
\D | 匹配一个非数字字符。 等价于 [^0-9] 。 |
{n} | n 是一个正整数,匹配了前面一个字符刚好出现了 n 次。 |
{n,} | n 是一个正整数,匹配前一个字符至少出现了 n 次。 |
{n, m} | n 和 m 都是整数。匹配前面的字符至少 n 次,最多 m 次。如果 n 或者 m 的值是 0,这个值被忽略。 |
g | 全局匹配 |
三、千位符正则解析
有了上面的基础,我们对千位符的正则进行解析
str.replace(str.indexOf('.') > -1 ? /(\d)(?=(\d{3})+\.)/g : /(\d)(?=(?:\d{3})+$)/g, '$1,')
1. 是否有小数点
首先判断 是否是有小数点,有小数则使用
/(\d)(?=(\d{3})+\.)/g ①
没有小数则使用
/(\d)(?=(?:\d{3})+$)/g ②
区别在哪里呢?
匹配了小数点结尾,在两者的 (? = x) 中,正则 ① 的匹配项x为 (\d{3})+\. , 正则 ② 的匹配项x为 (?:\d{3})+$ ,可以看到,①的匹配项中 \.代表以 . 结尾,而②的匹配项则以数字结尾
2. 具体解析
对正则 ① 进行拆分如下:
/ (\d)(?=x) / 匹配以 x 结尾的数字 \d。
x = (\d{3}+\.) 其中\d{3}表示数字出现3次,\d{3}+ 就代表 \d{3} 出现一次及以上,大白话理解含义则是三个数字一组,可以有多组。x含义则是出现3的倍数的数字且该数字以.结尾
那么总的理解就是,匹配一个数字,这个数字 后面的数字个数 是 3的倍数。
到这里应该理解了正则①的含义,接下来我们用代码验证一下该字符串匹配了些什么
const hhh = '587454151.12345'
console.log( hhh.match(/(\d)(?=(\d{3})+\.)/g) ) // ['7', '4']
那么正则②就很好理解了,
/ (\d)(?=x) / 匹配以 x 结尾的数字 \d。
x = (?:y)+$ x表示多个 y 且以 y 结尾的字符串
y = (\d{3}) y表示3个连续出现的数字
那为什么正则 ② 多一个非捕获括号呢?让我们用代码验证一下非捕获括号的区别:
const ggg = '587454151'
// 有非捕获括号(?:y)
ggg.match(/(\d)(?=(?:\d{3})+$)/g) // ['7', '4']
//无非捕获括号 (?:y)
ggg.match(/(\d)(?=(\d{3})+$)/g) // ['7', '4']
嘿嘿嘿,在这个场景上是没啥区别的,记得加括号就好,不然会报错。
3. str.replace(reg, arg)
参数的具体解析可见官网
String.prototype.replace() - JavaScript | MDN
特殊替换模式
'$1,' 表示:匹配到的第一个捕获组(括号括起来的) 和逗号 “ , ” 拼在一起,注意必须和正则表达式一起用才生效
若有错误请批评指正,感谢~