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脚本的10个技巧(3)
Oct 09 PHP
模仿OSO的论坛(三)
Oct 09 PHP
php 静态变量与自定义常量的使用方法
Jan 26 PHP
GBK的页面输出JSON格式的php函数
Feb 16 PHP
PHP similar_text 字符串的相似性比较函数
May 26 PHP
php文件上传的例子及参数详解
Dec 12 PHP
php-fpm配置详解
Feb 12 PHP
php实现图片添加描边字和马赛克的方法
Dec 10 PHP
phpStudy访问速度慢和启动失败的解决办法
Nov 19 PHP
Yii框架防止sql注入,xss攻击与csrf攻击的方法
Oct 18 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
PHP策略模式写法
Apr 01 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加密解密的代码
2007/07/16 PHP
laravel5 Eloquent 实现事务方式
2019/10/21 PHP
javascript 动态修改样式和层叠样式表代码
2010/04/27 Javascript
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
2010/07/26 Javascript
JavaScript版DateAdd和DateDiff函数代码
2012/03/01 Javascript
JavaScript 高级篇之DOM文档,简单封装及调用、动态添加、删除样式(六)
2012/04/07 Javascript
jquery动态加载js/css文件方法(自写小函数)
2014/10/11 Javascript
JS数字抽奖游戏实现方法
2015/05/04 Javascript
谈谈JSON对象和字符串之间的相互转换JSON.stringify(obj)和JSON.parse(string)
2015/10/01 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
深入学习jQuery Validate表单验证(二)
2016/01/18 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
2016/04/29 Javascript
JS中this上下文对象使用方式
2016/10/09 Javascript
AngularJS全局scope与Isolate scope通信用法示例
2016/11/22 Javascript
JS判断输入的字符串是否是数字的方法(正则表达式)
2016/11/29 Javascript
js实现多张图片延迟加载效果
2017/07/17 Javascript
元素全屏的设置与监听实例
2017/11/28 Javascript
Vue+ElementUI实现表单动态渲染、可视化配置的方法
2018/03/07 Javascript
基于JS实现一个随机生成验证码功能
2019/05/29 Javascript
javascript实现的图片预览和上传功能示例【兼容IE 9】
2020/05/01 Javascript
python实现RSA加密(解密)算法
2016/02/17 Python
Python金融数据可视化汇总
2017/11/17 Python
Python3 queue队列模块详细介绍
2018/01/05 Python
Python将DataFrame的某一列作为index的方法
2018/04/08 Python
Django实战之用户认证(初始配置)
2018/07/16 Python
Python如何调用JS文件中的函数
2019/08/16 Python
浅谈Python中re.match()和re.search()的使用及区别
2020/04/14 Python
Python下使用Trackbar实现绘图板
2020/10/27 Python
CSS3控制HTML元素动画效果
2014/02/08 HTML / CSS
优秀的个人求职信范文
2014/05/09 职场文书
委托培训协议书
2014/11/17 职场文书
房产证明范本
2015/06/19 职场文书
公司出差管理制度范本
2015/08/05 职场文书
MySQL中utf8mb4排序规则示例
2021/08/02 MySQL
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB
Nginx 匹配方式
2022/05/15 Servers