我们举例从字符串 "abZW863ab8"中获取 "ab863"
let str = "abZW863ab8";
例1 str.match(/ab(?=[A-Z]+)[A-Z]+\d+/g);// 输出结果 ["abZW863"]
例2 str.match(/ab(?=[A-Z]+)/g); // 输出结果["ab"]
例3 str.match(/ab(?=[A-Z]+)\d+/g);//输出结果 null
理解正则
写一些匹配规则,从左到右去校验匹配字符串,发现当前字符符合本次正则的校验,就会抵消掉该字符在整个字符串的校验,同时抵消掉该正则,进行下一轮的正则校验,
案例分析
1.例如正则中的ab匹配到字符中的ab,就会抵消掉对字符串中ab字符的校验,同时抵消掉正则ab 的校验, 进入下一轮正则的校验,
2. 此时正则ab后出现了断言
(?=[A-Z]+),断言是零宽的,意思是正则会拿着断言 (?=[A-Z]+)对当前字符串中的字符 ZW(ZW: ab字符抵消后,是ZW字符。 ab正则抵消后,是断言(?=[A-Z]+。 对应抵消校验。)
)
进行校验,但是断言只会抵消匹配字符的正则,不会抵消匹配到字符串中的字符,这样字符还是存在的,正则却进入了下一轮
3.下一轮的正则会对断言未抵消掉的字符在次匹配校验,
如例3断言 (?=[A-Z]+) 先是匹配校验字符ZW,但是没有抵消掉字符ZW的校验,导致本应该去匹配数字86的\d+正则 再次去校验字符ZW ,从而导致整个正则出现了不匹配,我们在例1中做了证实,将断言部分在写一遍,这部分替代了因零宽未抵消匹配字符的错误,所以例1成立
4. 例2:说明断言后没有正则校验,也就不会出现错位校验,这是常用的断言方式
5. 解决该问题可以用捕获组,拼接字符(多种方式不一列举,目的只为讲明断言后的正则匹配问题)
let capture = /(?ab)[A-Z]+(?\d+)/g.exec(str);
capture.groups.groupA + capture.groups.groupB;// 得到想要的结果 "ab863"