预查

不消耗匹配的字符: 就像字符串的替换方法 replace(/reg/,  'abc')   中如果对字符串“---regx----”  执行这个方法,结果就是 “---abc----”,

          "---regx----".replace(/(?<=reg)x/,'abc') 结果是 "---regabc----" , 其中“reg” 并没有被替换掉

正向预查    (?Tpattern) 

其中T可以是 :   !  =  三种,分别表示  不存储,不等于,等于

不存储:即不能使用\n,来引用

栗子:

  1. 12001200,  12(?:0)+12\1  ==>  120+12\1  匹配不到,  12(0)+12\1 匹配到  ==> (?:0)没有被存储,\1取不到,同理=和!也是不存储
  2. Java(?=6), java6java7==>java6
  3. Java(?!6),  java6java7==>java7

 

反向预查   (?<Tpattern) , T的含义和正向预查一样的

栗子:

  1. (?<=\d)-\d, 1-2-4-6-a-1 ==>-2,-4,-6
  2. (?<!\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>”中的“>”替换成“&gt;”,但是不影响“<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”),则使用“&gt;”替换

posted on 2018-12-12 17:07  白刃红尘  阅读(219)  评论(0)    收藏  举报