PHP之正则表达式捕获组与非捕获组(详解)


Posted in PHP onJuly 29, 2015

在项目开发过程中正则表示经常会用到,可以说会正则表达式是每个程序员最基本的要求,初学者在刚接触正则表达式都感到很吃力。最近看到一位朋友的博客写的《PHP正则表达式》获益颇多,在章节对通配符以及捕获数据非常感兴趣。这两章节刚好也涉及到了正则表达式的捕获组和非捕获组的内容,以此来分析这方面的内容

我们知道,在正则表达式下(x) 表示匹配'x'并记录匹配的值。这只是比较通俗的说法,甚至说这是不严谨的说法,只有()捕获组形式才会记录匹配的值。非捕获组则只匹配,不记录。

捕获组:

(pattern)

这种形式是我们见到最多的一种形式,匹配并返回捕获结果,可以嵌套,组号顺序从左到右依次排列‘。

$regex = '/(ab(c)+)+d(e)?/';    

$str = 'abccde';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => abccde [1] => abcc [2] => c [3] => e )
(?P<name>pattern)

这种方式虽然看起来在构造正则表达式的时候略微复杂一点,但实质上与(pattern)一样。最大的优势体现在对结果处理上,程序员可以直接根据自己设置的<name>直接快速调用结果,而不用再去数需要的结果在第几个子组了。

$regex = '/(?P<group1>\w(?P<group2>\w))abc(?P<group3>\w)45/';
$str = 'fsabcd45';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}
 

匹配结果:

Array ( [0] => fsabcd45 [group1] => fs [1] => fs [group2] => s [2] => s [group3] => d [3] => d )
\num

num是一个整数,是对捕获组的反向引用。  例如\2表示第二个子组匹配值,\表示第一个子组匹配值

$regex = '/(\w)(\w)\2\1/';    

$str = 'abba';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => abba [1] => a [2] => b )

注意,这里我疏忽了一个小细节,一开始我第一样代码是 $regex = “/(\w)(\w)\2\1/”;  结果返回无匹配结果,经过调试后,发现这里只能用' '。'与" 用法差别大家还是需要注意下。

  \k< name >

了解了(?P<name>pattern)与\num,这个就不难理解了。\k< name >是对命名捕获组的反向引用。其中 name 是捕获组名。

$regex='/(?P<name>\w)abc\k<name>/';
$str="fabcf";

echo preg_match_all($regex, $str,$matches);

print_r($matches);

匹配结果:

Array ( [0] => Array ( [0] => fabcf ) [name] => Array ( [0] => f ) [1] => Array ( [0] => f ) )

非捕获组:

(?:pattern)

与(pattern)的唯一区别是,匹配pattern但不捕获匹配结果。这里便不再举例。

还有四种方式实际上讲的是一个事情:预查。

预查分为正向预查与反向预查。根据字面理解,正向预查是判断匹配字符串后面某些字符存在与否,而反向预查则是判断匹配字符串前面某些字符存在与否。

正向预查判断存在使用(?=pattern),判断不存在使用(?!pattern)。

反向预查判断存在使用(?<=pattern),判断不存在使用(?<!pattern)。

$regx='/(?<=a)bc(?=d)/';
$str="abcd ebcd abce ebca";

if(preg_match_all($regx, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => Array ( [0] => bc) )

这四种形式使用的是否只要注意好相对匹配字符串的位置和断言肯定还是否定,就会很快掌握。

另外,预查的四种形式是零宽度的,匹配的时候只做一个判断,本身是不占位置的。/HE(?=L)LLO/ 与HELLO匹配,而/HE(?=L)LO/与HELLO是不匹配的。毕竟但从字节数上两者就是不匹配的,前者只有4个,而后者有5个。

以上就是PHP之正则表达式捕获组与非捕获组详解的全部内容,希望对大家有所启迪。

PHP 相关文章推荐
PHP_MySQL教程-第一天
Mar 18 PHP
由php if 想到的些问题
Mar 22 PHP
PHP 文件上传源码分析(RFC1867)
Oct 30 PHP
ThinkPHP利用PHPMailer实现邮件发送实现代码
Sep 26 PHP
php中json_encode处理gbk与gb2312中文乱码问题的解决方法
Jul 10 PHP
php实现获取文章内容第一张图片的方法
Nov 04 PHP
PHP调用Linux命令权限不足问题解决方法
Feb 07 PHP
php结合正则获取字符串中数字
Jun 19 PHP
WordPress主题中添加文章列表页页码导航的PHP代码实例
Dec 22 PHP
laravel中的错误与日志用法详解
Jul 26 PHP
Laravel框架路由设置与使用示例
Jun 12 PHP
windows系统php环境安装swoole具体步骤
Mar 04 PHP
PHP实现的简单缓存类
Jul 29 #PHP
PHP实现简单爬虫的方法
Jul 29 #PHP
php获取网站百度快照日期的方法
Jul 29 #PHP
如何通过Linux命令行使用和运行PHP脚本
Jul 29 #PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 #PHP
PHP模拟QQ登录的方法
Jul 29 #PHP
PHP实现动态web服务器方法
Jul 29 #PHP
You might like
PHP开发文件系统实例讲解
2006/10/09 PHP
PHP实现MVC开发得最简单的方法――模型
2007/04/10 PHP
jquery ajax 简单范例(界面+后台)
2013/11/19 Javascript
jQuery CSS()方法改变现有的CSS样式表
2014/09/09 Javascript
js实现图片漂浮效果的方法
2015/03/02 Javascript
基于jQuery实现的扇形定时器附源码下载
2015/10/20 Javascript
谈谈AngularJs中的隐藏和显示
2015/12/09 Javascript
基于jQuery实现Ajax验证用户名是否存在实例
2016/03/30 Javascript
js实现精确到毫秒的倒计时效果
2016/08/05 Javascript
详解Vue 2.0封装axios笔记
2017/06/22 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
vue-router 手势滑动触发返回功能
2018/09/30 Javascript
基于layui table返回的值的多级嵌套的解决方法
2019/09/19 Javascript
vue3 watch和watchEffect的使用以及有哪些区别
2021/01/26 Vue.js
给Python的Django框架下搭建的BLOG添加RSS功能的教程
2015/04/08 Python
python中requests和https使用简单示例
2018/01/18 Python
opencv改变imshow窗口大小,窗口位置的方法
2018/04/02 Python
python遍历文件夹,指定遍历深度与忽略目录的方法
2018/07/11 Python
对sklearn的使用之数据集的拆分与训练详解(python3.6)
2018/12/14 Python
使用Fabric自动化部署Django项目的实现
2019/09/27 Python
Python 私有化操作实例分析
2019/11/21 Python
Python异常继承关系和自定义异常实现代码实例
2020/02/20 Python
Python脚本如何在bilibili中查找弹幕发送者
2020/06/04 Python
匡威比利时官网:Converse Belgium
2017/04/13 全球购物
全球性的奢侈品梦工厂:Forzieri(福喜利)
2019/02/20 全球购物
Bata印度官网:源自欧洲舒适鞋履品牌
2020/01/30 全球购物
个人委托书范本
2014/04/02 职场文书
留学推荐信范文
2014/05/10 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
承诺函格式模板
2015/01/21 职场文书
个人总结与自我评价2015
2015/03/11 职场文书
教师节联欢会主持词
2015/07/04 职场文书
2015教师个人德育工作总结
2015/07/22 职场文书
2015年依法治校工作总结
2015/07/27 职场文书
Java基础之线程锁相关知识总结
2021/06/30 Java/Android
分析SQL窗口函数之排名窗口函数
2022/04/21 Oracle