正则表达式-零宽断言

前言:今天在浏览 laravel-china 的时候,发现了一篇浅析 Laravel 官方文档推荐的 Nginx 配置,
里面提到了零宽断言,在闹钟一搜索,发现没有这个词汇,故在此查阅资料总结。

概念:

零宽断言,所谓零宽就是宽度为0,断言就是判断,综合起来我理解就是判断被正则的字符串是否出现待匹配的正则表达式,但是,如果
出现,匹配到判断的正则表达式的字符串不出现在匹配结果中(因为是零宽度,所以不显示)。

具体操作:

通过查阅资料,发现有四种类型的零宽断言,分别是:

  • 正先行断言
  • 反先行断言
  • 正后发断言
  • 反后发断言

下面就对上面四种类型的零宽断言分别做一个描述。

先行断言

在特殊正则字符串相应位置之前匹配,先行断言又分未正先行断言和反先行断言。

正先行断言

特殊正则字符串((?=exp))应该出现在需要被匹配的字符串之后,但是匹配结果不应该出现特殊正则字符串所匹配的结果。如下例所示:

<?php
//获取后缀为 .jpg 的图片地址的除 .jpg 剩下的部分。
// ($pattern)(?=exp)

preg_match("/.*(?=\.jpg)/","image1.jpg",$match);
var_dump($match); // ['image1']

//上例匹配了后缀为 .jpg 的字符串,但是匹配的结果中没有 .jpg。

反先行断言

特殊正则字符串( (?!exp))应该不出现在需要被匹配的字符串之后,但是匹配结果不应该出现特殊正则字符串所匹配的结果。如下例所示:

<?php
//获取后缀不为 .jpg 的图片地址的除 .jpg 剩下的部分。
// ($pattern)(?!exp)

preg_match("/(image1\.)(?!jpf)/","image1.jpf",$match);
var_dump($match); // [''] 因为存在了 jpf 的后缀

preg_match("/(image1\.)(?!jpf)/","image1.jpg",$match);
var_dump($match); // ['iamge1.','iamge1.'] 

后行断言

在特殊正则字符串相应位置之后匹配,先行断言又分未正后行断言和反后行断言。

正后行断言

特殊正则字符串( (?<=exp))应该出现在需要被匹配的字符串之前,但是匹配结果不应该出现特殊正则字符串所匹配的结果。如下例所示:

<?php
//获取https域名地址。
// (?<=exp)($pattern)

preg_match("/(?<=https:\/\/).*/","https://www.snail-c.cn",$match);
var_dump($match); // ['www.snail-c.cn']

//上例匹配了https协议的域名地址

反后行断言

特殊正则字符串((?<!exp))应该不出现在需要被匹配的字符串之前,但是匹配结果不应该出现特殊正则字符串所匹配的结果。如下例所示:

<?php
//获取https域名地址的除。
// (?<=exp)($pattern)

preg_match("/(?<!https:\/\/)(www\.snail-c\.cn)/","https://www.snail-c.cn",$match);
var_dump($match); // [] 因为存在了https,所以什么都不能匹配

preg_match("/(?<!https:\/\/)(www\.snail-c\.cn)/","http://www.snail-c.cn",$match);
var_dump($match); // ["http://www.snail-c.cn","http://www.snail-c.cn"] 因为 www.snail-c.cn 前面不是 https 所以正常匹配
综上所述,其实零宽断言就是判断被断言的正则是否存在某字符串中,但是断言所匹配的结果不应该出现在结果中。

Snail's Blog
请先登录后发表评论
  • 最新评论
  • 总共0条评论
  • 本博客使用免费开源的 laravel-bjyblog v5.5.1.3 -develop 搭建 © 2014-2018 www.snail-c.cn 版权所有 ICP证:蜀ICP备18023253号-1
  • 联系邮箱:459921737@qq.com