精通正则表达式-什么是零宽断言

零宽断言是正则表达式的精华所在,然而真正理解它的人却不多。其实MSDN中给出了零宽断言的定义,直白的翻译为中文就是:零宽断言并不匹配具体字符,而是匹配一个位置。只有当匹配位置满足指定条件后,与其相关的表达式的匹配才成立。对于这句拗口的解释,大多数人并不愿意深究(或者干脆认为MSDN在胡扯),而是宁愿自己通过实践总结规律。不得不承认,有很多人总结出了一些简单实用的规律(比如w3shool对^n和n$还有正负先行预测的解释)。然而因为理解的不够全面,让零宽断言的强大功能大打折扣。下面就让我把自己耗费整整一周的成果献给大家。

要理解零宽断言,关键就是要理解它并不匹配具体字符。而是只匹配一个位置。这里需要分清两个概念----正则表达式中零宽断言的位置和匹配字符串中它的匹配位置。让我们看一个正先行预测的例子:
function fucTest()
{
var sString='some other words Jack is a good boy! some other words'; //要进行匹配的字符串
var rRegExp=/Jack is (?=a)a good boy!/; //要进行匹配的正则表达式
var aResult=rRegExp.exec(sString); //进行匹配
alert(aResult[0]); //输出匹配结果
}
输出:
Jack is a good boy!
有些人会问:子表达式'(?=a)'里不是已经有a了吗?为什么还要在'(?=a)'后面再加一个a?
其实这就是问题的关键所在。因为正先行预测和所有其他的零宽断言一样,并不匹配具体字符。而是只匹配一个位置。让我们通过这个例子来解释一下这个概念。
1.零宽断言的位置:
在本例中零宽断言是正先行预测'(?=a)'。它的位置就是它在正则表达式里的位置。又由于正先行预测的‘前面相关’特性。所以本例中零宽断言的位置就是正则表达式里'Jack is '(注意is后面有空格符)后面的位置。
2.零宽断言的匹配位置:
而它的匹配位置就是匹配字符串‘Jack is a good boy!’里的对应位置。即匹配字符串里'Jack is '后面的位置。
3.匹配条件:
下面我们再讨论匹配位置所要满足的条件。正预测先行'(?=a)'里的'?=a'就是这个条件。意思是处于匹配位置的字符必须是'a'。

下面我们从头理解一下上面例子的匹配过程:
首先寻找正预测先行的匹配位置,即字符串里'Jack is '后面的位置。然后判断该位置是否满足条件,即处于该位置的字符是否为'a'。最后匹配正预测先行前面的表达式。即正则表达式里的'Jack is '。至此,与正预测先行相关的匹配结束。然后,再进行正预测先行之后的匹配,即正则表达式里的'a good boy'。

相信有了上面的解释大家都能对零宽断言有一个清晰的认识。其它的零宽断言(如后发预测),我就不赘述了。留给大家一些自己实践的空间

吧。

相关文档
最新文档