引用自百度百科:零宽断言是正则表达式中的一种方法,正则表达式在计算机科学中,是指一个用来描述或者匹配一系列符合某个句法规则的字符串的单个字符串。

通常我们按照一定规则通过正则表达式匹配一段字符串的时候,我们给出的规则文本也会包含在内,比如以下这个例子,我们要匹配出被”#~”和”~#”包裹的文本:

1
2
3
4
5
6
7
8
var reg = "#~.*?~#";
var text = "这是一段#~测试~#文字,用来测试#~正则表达式~#。";
var matches = Regex.Matches(text.reg);
foreach (Match match in matches)
{
Console.WriteLine(match);
}
Console.ReadKey();

运行以上C#代码,我们将会看到输出的是:

1
2
#~测试~#
#~正则表达式~#

但是有些时候,我们不希望规则文本出现在结果之中。这时候我们就需要用上”零宽断言“了。我们只需稍稍修改一下正则的代码:

1
var reg = "(?<=#~).*?(?=~#)";

其他代码不变,此时输出的就是:

1
2
测试
正则表达式

这里用上的(?<=表达式)和(?=表达式)就是零宽断言中的两种形式,前者称为”零宽度正回顾后发断言“,后者称为”零宽度正预测先行断言“。

以上面的代码为例,零宽度正预测先行断言(即(?=表达式))的规则是先从给出的文本中找到第一个”~#”,然后再回过头看看”~#”前面的文本是否符合”.*”这个规则,如果符合则进行匹配,不符合则查找下一个”~#”,然后再重复以上步骤。

零宽度正回顾后发断言(即(?<=表达式))则正好相反,它是先从要匹配的字符串中的最左端找到”#~”,然后看后面的文本是否符合”.*”这个规则,如果是则匹配,如果不是再去找第二个。

当然,还有”负向零宽后发断言(?<!表达式) “和”负向零宽先行断言 (?!表达式) “两种,这两种是找到第一个不匹配表达式的,然后再去做相应判断。

注意,在Javascript中,不支持后发断言,但是在Chrome浏览器中可以正常使用后发断言,这点需要注意一下,否则在Chrome中测试通过的代码,可能换了FireFox就不行了。