前言:
环视就是断言
正则匹配是从前往后的,断言匹配的是位置,是"零宽"的
分类:
让我们看一个正则匹配,匹配带字符'o'的单词,在此基础上说明断言
let str = `hello world, I'm your brother`
// 匹配带有字符o的单词
console.log( str.match(/[a-z]{0,}o[a-z]{0,}/g) )
//=> ['hello', 'world', 'your', 'brother']
1、先行断言 (?=p)
匹配某个位置,其右边一定是p表达式
// 匹配字符o,右边一定是r或u
console.log( str.match(/[a-z]{0,}o(?=[ru])[a-z]{0,}/g) )
//=> ['world', 'your']
// 匹配字符o,右边第二个字符一定是l
console.log( str.match(/[a-z]{0,}o(?=.l)[a-z]{0,}/g) )
//=> ['world']
2、先行反向断言(?!=p)
匹配某个位置,其右边一定不是p表达式
// 匹配字符o,右边一定不是r
console.log( str.match(/[a-z]{0,}o(?!r)[a-z]{0,}/g) )
//=> ['hello', 'your', 'brother']
3、后行断言(?<=p)
匹配某个位置,其左边一定是p表达式
// 匹配字符o,左边一定是y
console.log( str.match(/[a-z]{0,}(?<=y)o[a-z]{0,}/g) )
//=> ['your']
4、后行反向断言(?<!p)
匹配某个位置,其左边一定不是p表达式
注意:是?<!,不要写错了
// 匹配字符o,左边一定不是br
console.log( str.match(/[a-z]{0,}(?<!br)o[a-z]{0,}/g) )
//=> ['hello', 'world', 'your']
注意:
零宽,不占位
'your'.match(/yo(?=[abu])/)
//=> ['yo', index: 0, input: 'your', groups: undefined]
'your'.match(/yo[abu]/)
//=> ['you', index: 0, input: 'your', groups: undefined]
拓展:
// 实现参数数字的千分位分隔符字符串
// 输入数字1234567,输出字符串'1,234,567'
// 输入数字-12345, 输出字符串'-12,345'
function comma(num){
let str = num.toString()
return str.replace(/(\d)(?=(\d{3})+$)/g, '$1,')
// $1匹配的是第一个分组(\d)
// (?=(\d{3})+$) 是先行断言,表示可以匹配到至少一个 \d{3} ,最后的位置一定是$
}
console.log( comma(1234567) ) //=> '1,234,567'
console.log( comma(-12345) ) //=> '-12,345'
参考链接: