正则表达式之——先行断言(lookahead)和后行断言(lookbehind)

正则表达式的先行断言和后行断言一共有4种形式: 

  1. (?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion) 
  2. (?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion) 
  3. (?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion) 
  4. (?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion) 

这里面的pattern是一个正则表达式。

如同^代表开头,$代表结尾,\b代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中不占用字符,所以被称为“零宽”。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)。 下面分别举例来说明这4种断言的含义。

1、(?=pattern) 正向先行断言: 
代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配pattern。 
例如对”a regular expression”这个字符串,要想匹配regular中的re,但不能匹配expression中的re,可以用”re(?=gular)”,该表达式限定了re右边的位置,这个位置之后是gular,但并不消耗gular这些字符,将表达式改为”re(?=gular).”,将会匹配reg,元字符.匹配了g,括号这一砣匹配了e和g之间的位置。

2、(?!pattern) 负向先行断言 :
代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配pattern。 
例如对”regex represents regular expression”这个字符串,要想匹配除regex和regular之外的re,可以用”re(?!g)”,该表达式限定了re右边的位置,这个位置后面不是字符g。负向和正向的区别,就在于该位置之后的字符能否匹配括号中的表达式。

3、(?<=pattern) 正向后行断言 
代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配pattern。 
例如对”regex represents regular expression”这个字符串,有4个单词,要想匹配单词内部的re,但不匹配单词开头的re,可以用”(?<=\w)re”,单词内部的re,在re前面应该是一个单个字符。之所以叫后行断言,是因为正则表达式引擎在匹配字符串和表达式时,是从前向后逐个扫描字符串中的字符,并判断是否与表达式符合,当在表达式中遇到该断言时,正则表达式引擎需要往字符串前端检测已扫描过的字符,相对于扫描方向是向后的。

4、(?<!pattern) 负向后行断言 
代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配pattern。 
例如对”regex represents regular expression”这个字符串,要想匹配单词开头的re,可以用”(?<!\w)re”。单词开头的re,在本例中,也就是指不在单词内部的re,即re前面不是单个字符。当然也可以用”\bre”来匹配。

 

对于这4个断言的理解,可以从两个方面入手:

1)关于先行(lookahead)和后行(lookbehind):正则表达式引擎在执行字符串和表达式匹配时,会从头到尾(从前到后)连续扫描字符串中的字符,设想有一个扫描指针指向字符边界处并随匹配过程移动。先行断言,是当扫描指针位于某处时,引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。后行断言,引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。 

2)关于正向(positive)和负向(negative):正向就表示匹配括号中的表达式,负向表示不匹配。

对这4个断言形式的记忆: 

1)先行和后行:后行断言(?<=pattern)、(?<!pattern)中,有个小于号,同时也是箭头,对于自左至右的文本方向,这个箭头是指向后的,这也比较符合我们的习惯。把小于号去掉,就是先行断言。 

2)正向和负向:不等于(!=)、逻辑非(!)都是用!号来表示,所以有!号的形式表示不匹配、负向;将!号换成=号,就表示匹配、正向。

 

转自:http://blog.51cto.com/cnn237111/749047

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值