今天分享一下正则表达式里强大的利器: 零宽度断言 (先行断言和后行断言)
零宽度断言,也称为环视,是一种特殊的结构,它用于匹配一个位置,该位置的前后满足特定的条件,但这些条件不会被包含在最终的匹配结果中,它分为先行断言和后行断言
先行断言
先行断言用于检查某个位置后面的字符是否满足特定条件,但不消耗这些字符,分为两类:
- 正向先行断言
- 使用 (?=pattern) 语法,表示当前位置后面的字符必须匹配 pattern
- pattern 本身不会被包含在匹配结果中
// 匹配文本里所有%前面的数字
'20% 10% a% % ddd 60%'.match(/\d+(?=%)/g)
// [20,10,60]
//// 将文本里所有带%的数字添加小数点
'20% 10% a% % ddd 60%'.replace(/(\d+)(?=%)/g,(m,p)=>{
return m+'.00'
})
// '20.00% 10.00% a% % ddd 60.00%'
- 负向先行断言(先行否定断言)
- 使用 (?!pattern) 语法,表示当前位置后面的字符不能匹配 pattern
- pattern 本身不会被包含在匹配结果中
//匹配不是%结尾的数字,
//这里需要加单词边界\b,不然会匹配到6
'20$ 10¥ a% % ddd 60%'.match(/\d+\b(?!%)/g)
// ['20', '10']
后行断言
后行断言用于检查某个位置前面的字符是否满足特定条件,但不消耗这些字符。有两种类型:
正向后行断言
- 使用 (?<=pattern) 语法,表示当前位置前面的字符必须匹配 pattern
- pattern 本身不会被包含在匹配结果中
//匹配文本内所有$开头的数字
//$美元符需要加反斜杠转义
'¥20 $10 $a % ddd $60'.match(/(?<=\$)\d+/g)
//['10','60']
负向后行断言
- 使用 (?
- pattern 本身不会被包含在匹配结果中
//匹配文本内所有非$开头的数字
//$美元符需要加反斜杠转义
//数字前需要加单词边界\b
'¥20 ¥10 $a % ddd $60'.match(/(?
PS: 对于先行和后行可以这么理解
- 匹配的字符在pattern之前,可以理解为先行
- 匹配的字符在pattern之后,可以理解为后行