感谢本文参考《正则表达式迷你书》位置匹配什么是位置位置就是空字符串。每一个字符不是位置, 正则中的位置可以理解如下// 空字符串就是位置"hello" == "" + “h” + "" + “e” + "" + “l” + "" + “l” + "" + “o” + “”;“hello” == "" + "" + “hello"如何匹配位置位置含义^匹配开头。多行匹配, 匹配行开头$匹配结尾。多行匹配, 匹配行结尾b单词边界, 可以是w与W, w与^, w与$之间的位置B非单词边界, w与w(字符与字符之间), W与W, ^与W, $与W之间的位置(?=p)p为一个子模式, (?=p)表示p字符前面的位置, (?=l)表示l字符前面的位置。换一种说法, 位置后面的字符需要是p, 这个位置就是满足正则的位置(?!p)(?!p)是(?=p)的取反, 所有非(?=p)的位置。例如(?!^)所有非开头前面的位置。^ 和 $单行匹配// “#Hello World#“console.log(“Hello World”.replace(/^|$/g, ‘#’))多行匹配存在修饰符n, ^$匹配的是每一行的开头和结尾。正则表达式需要添加m全局模式// “#Hello#// #World#“console.log(‘Hello\nWorld’.replace(/^|$/gm, ‘#’))b 和 Bbb匹配的都是单词边界// []#I# #L#[] [#ove#] #you# #Fang#[]#Fang#!!!!”[]I L[] [ove] you Fang[]Fang!!!!".replace(/\b/g, ‘#’)]I 为单词的边界L[ 为单词的边界[o 为单词的边界e] 为单词的边界 y 为单词的边界u  为单词的边界 F 为单词的边界g[ 为单词边界]F 为单词边界g  为单词边界BB匹配的是所有非单词边界, b的取反// #[#]I L[#]# #[o#v#e]# y#o#u F#a#n#g!#!#!#!#”[]I L[] [ove] you F#a#n#g!!!!".replace(/\B/g, ‘#’)(?=p) 和 (?!p)p为子模式, p的位置可以是其他的正则表达式(?=p) 正向先行断言// 所有空的字符前面添加#// p前面总共有3个空字符, 所以添加3个#// ‘# # # p’’ p’.replace(/(?=[\s])/g, ‘#’)(?!p) 负向先行断言(?=p)位置的取反位置// 所有非空字符的前面// ’ #p#’’ p’.replace(/(?![\s])/g, ‘#’)案例不匹配任何字符的正则// .表示通配符, 但是开头在却在字符的后面, 任何字符都不会满足var reg = /.^/千位分割符可以使用(?=)正向先行断言, 配合d{3}的子模式。(?=(d{3})$), 表示了从结尾开始, 后面有3个数字的位置, 因为不能包含结尾,所以不能是任意三个数字(123, 234这种形式)。因为我们需要匹配多组这种位置可以使用量词+。(?=(d{3})+$)“位置” + 123 + “位置” + 456 + $(结尾)var reg = /(?=(\d{3})+$)/g// “,123,456,789"“123456789”.replace(reg, ‘,’)这里我们遇到一个问题, 由于字符串开头(^)也符合正则的要求, 所以会导致这里也会添加一个逗号, 如何去除这个逗号呢?有两种方式。第一种使用B, 因为逗号必须添加在非单词边界中。第二种方式是使用负向先行断言(?!^), 要求了匹配的位置后面不能是开头。var reg1 = /\B(?=(\d{3})+$)/g// “123,456,789"“123456789”.replace(reg1, ‘,’)var reg2 = /(?!^)(?=(\d{3})+$)/g// “123,456,789"“123456789”.replace(reg2, ‘,’)???? 题外话, 当初我在看书的解答前也思考了这个问题, 我的想法如下var reg = /^^/g// “12,45,789"“123456789”.replace(reg, ‘,’)结果是"12,45,789”, 经过思考我发现自己陷入了一个思维的误区。我们这里需要匹配的是位置而为字符这很重要!reg的含义是, 后面跟有3个数字并且前面本身不是开头的字符, 而非位置, 从思维上区分位置和字符很重要???? 正则表达式中匹配位置的只有^, $, b, B, (?=p), (?!p)// ^表示的是位置"123456789”.replace(/^/g, ‘,’)// [^^]表示的是字符"1 23456789”.replace(/[^^]/g, ‘,’)如果此时字符串变成了"123456789 123456789”, 我们依然需要给字符中添加千位分割符, 我们又该如何做呢?我们来分析下目前的情况, 这一个字符串中中间有一个space, 我们这时不能继续使用$, 因为如果使用$, space之前的字符将不能匹配, 因为无法满足(d{3})+子模式的条件。我们可以将$, 替换成b, 表示从单词的边界开始, 前面三个数字之前的那个位置// “,123,456,789 ,123,456,789"“123456789 123456789”.replace(/(?=(\d{3})+\b)/g, ‘,’)我们同时不能在单词的边界处添加逗号, 所以可以使用B(非单词边界位置)或者(?!b)(非, 单词边界的前面, 的位置)// “123,456,789 ,123,456,789"“123456789 123456789”.replace(/\B(?=(\d{3})+\b)/g, ‘,’)“123456789 123456789”.replace(/(?!\b)(?=(\d{3})+\b)/g, ‘,’)????货币格式化"1888” ==> “$ 1888.00"var money = ‘1888’var reg1 = /(?=(^))/gvar reg2 = /$/gmoney = money.replace(reg1, ‘$ ‘)// “$ 1888.00"money = money.replace(reg2, ‘.00’)验证密码密码的验证规则, 6-12位, 由数字小写字母和大写字母组成, 必须包含两种字符。首先匹配第一个条件, 6-12位var reg = /^\w{6, 12}$/g必须包含数字// 表示是否存在, 包含数字的字符串, 前面的位置var reg = /(?=.[0-9])/g必须包含小写字母, 必须包含大写字母同理// 表示是否存在, 包含小写字母的字符串, 前面的位置var reg = /?=.[a-z]/g我们将上面的正则组合var reg = /((?=.[0-9])(?=.[a-z])|(?=.[0-9])(?=.[A-Z])|(?=.[a-z])(?=.[A-Z]))^\w{6,12}$/// trueconsole.log(reg.test(‘123dde121’))// trueconsole.log(reg.test(‘1231a311’))// falseconsole.log(reg.test(‘12z’))另一种思路包含两种类型的字符可以理解为不能全部是数字,不能全部是小写字母和不能全部是大写字母。?!是?=的区反。// 是否存在, “非”全部是数字的, 前面的位置var reg1 = /(?![0-9]{6,12})/// 是否存在, “非”全部是小写字母的, 前面的位置var reg2 = /(?![a-z]{6,12})/// 是否存在,“非”全部是大写字母的, 前面的位置var reg3 = /(?![A-Z]{6,12})/var reg = /(?![0-9]{6,12})|(?![a-z]{6,12})|(?![A-Z]{6,12})^\w{6,12}$/