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 上传文件类型判断函数(避免上传漏洞 )
Jun 08 PHP
php mssql扩展SQL查询中文字段名解决方法
Oct 15 PHP
php对称加密算法示例
May 07 PHP
php获取网页中图片、DIV内容的简单方法
Jun 19 PHP
非常好用的Zend Framework分页类
Jun 25 PHP
浅谈php安全性需要注意的几点事项
Jul 17 PHP
php输出金字塔的2种实现方法
Dec 16 PHP
php递归函数三种实现方法及如何实现数字累加
Aug 07 PHP
Zend Framework实现多文件上传功能实例
Mar 21 PHP
PHP实现动态执行代码的方法
Mar 25 PHP
PHP根据session与cookie用户登录状态操作类的代码
May 13 PHP
thinkPHP利用ajax异步上传图片并显示、删除的示例
Sep 26 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 strstr 函数判断字符串是否否存在的实例代码
2013/09/28 PHP
php中fsockopen用法实例
2015/01/05 PHP
php获取指定范围内最接近数的方法
2015/06/02 PHP
PHP连接MySQL数据库并以json格式输出
2018/05/21 PHP
thinkPHP框架动态配置用法实例分析
2018/06/14 PHP
PHP使用函数用法详解
2018/09/30 PHP
js禁止小键盘输入数字功能代码
2011/08/01 Javascript
Jvascript学习实践案例(开发常用)
2012/06/25 Javascript
js关闭浏览器窗口及检查浏览器关闭事件
2013/09/03 Javascript
JS中的异常处理方法分享
2013/12/22 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
使用requestAnimationFrame实现js动画性能好
2015/08/06 Javascript
延时加载JavaScript代码提高速度
2015/12/27 Javascript
js 判断一组日期是否是连续的简单实例
2016/07/11 Javascript
JS调用打印机功能简单示例
2016/11/28 Javascript
Angular使用操作事件指令ng-click传多个参数示例
2018/03/27 Javascript
微信小程序实现一张或多张图片上传(云开发)
2019/09/25 Javascript
JS自定义对象创建与简单使用方法示例
2020/01/15 Javascript
使用js实现单链解决前端队列问题的方法
2020/02/03 Javascript
jquery传参及获取方式(两种方式)
2020/02/13 jQuery
Python实现的各种常见分布算法示例
2018/12/13 Python
Python 一键获取百度网盘提取码的方法
2019/08/01 Python
美国祛痘、抗衰老药妆品牌:Murad
2016/08/27 全球购物
高三自我鉴定
2013/10/23 职场文书
函授本科自我鉴定
2013/11/03 职场文书
品质主管的岗位职责
2013/12/04 职场文书
大专生毕业的自我评价
2014/02/06 职场文书
物流业务员岗位职责
2014/02/08 职场文书
干部个人对照检查材料
2014/08/25 职场文书
工程部主管岗位职责
2015/02/12 职场文书
2015年世界艾滋病日活动总结
2015/03/24 职场文书
消防验收申请报告
2015/05/15 职场文书
个人催款函范文
2015/06/24 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
Python+OpenCV实现在图像上绘制矩形
2022/03/21 Python
win10双系统怎么删除一个系统?win10电脑有两个系统删除一个的操作方法
2022/07/15 数码科技