预查
不消耗匹配的字符: 就像字符串的替换方法 replace(/reg/, 'abc') 中如果对字符串“---regx----” 执行这个方法,结果就是 “---abc----”,
"---regx----".replace(/(?<=reg)x/,'abc') 结果是 "---regabc----" , 其中“reg” 并没有被替换掉
正向预查 (?Tpattern)
其中T可以是 : ! = 三种,分别表示 不存储,不等于,等于
不存储:即不能使用\n,来引用
栗子:
- 12001200, 12(?:0)+12\1 ==> 120+12\1 匹配不到, 12(0)+12\1 匹配到 ==> (?:0)没有被存储,\1取不到,同理=和!也是不存储
- Java(?=6), java6java7==>java6
- Java(?!6), java6java7==>java7
反向预查 (?<Tpattern) , T的含义和正向预查一样的
栗子:
- (?<=\d)-\d, 1-2-4-6-a-1 ==>-2,-4,-6
- (?<!\d)-\d, 1-2-4-6-a-1 ==>-1
另外的解释:
比如我们要匹配下面这个语句中的 “<” 后面不是 “br>” 的“<”:
<div>line1</div> <br>
这个正则表达式这么写: /<(?!br>)/
如果我们只匹配后面为“br>”的“<”呢,正则表达式这么写:
/<(?=br>)/
这两种语法在正则表达式中称之为:
(?=pattern) 零宽正向先行断言
(?!pattern) 零宽负向先行断言
断言的意思是判断是否满足,零宽的意思是它只匹配一个位置,如同^匹配开头,$匹配末尾一样,只是一个位置,不返回匹配到的字符,正向表示需要满足pattern,负向表示不能满足pattern,先行表示这个断言语句现在期望返回的匹配字符的后面。
我们在来假设一个需求,如果我要匹配不在“<br>”中的“>”,也就是说只匹配“<div>”、“</div>”中的“>”,而不匹配“<br>”中的“>”,那么要写的正则表达式就是“匹配前面没有'<br'的'>'”,写法如下:
/(?<!<br)>/
对应的如果只匹配“<br>”中的“>”,而不匹配“<div>”或者“</div>”中的“>”,就这么写:
/(?<=<br)>/
这两种语法在正则表达式中称之为:
(?<=pattern) 零宽正向后行断言
(?<!pattern) 零宽负向后行断言
与先行断言的意思一样,只不过后行断言写在需要匹配的字符的前面,表示如果前面的字符满足pattern就返回。
但是很遗憾的是javascript中并不支持这种后行断言。
那如果在javascript中我们想将“<div>”和“</div>”中的“>”替换成“>”,但是不影响“<br>”中的“>”,那怎么写呢,先看代码:
var s = "<div>line1</div> <br>";
var r = /(<br)?>/g;
s.replace(r, function($0, $1) { return $1?"":">";});
这里用到了replace函数的第二个参数,这个参数可以是一个值,也可以是一个函数,这个函数需要返回一个用于替换匹配结果的字符串,所以我们就可以利用这个函数的处理功能处理匹配到的结果,上面这个语句的意思就是使用“r”来匹配“s”,匹配之后“$0”中保存匹配到的完整结果,“$1”中匹配到“<br”,函数处理的结果就使,如果“$1”有值(表示“>”前面有“<br”),则返回一个空字符串(也就使不替换),如果“$1”没有值(表示“>”前面没有“<br”),则使用“>”替换
浙公网安备 33010602011771号