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往windows中添加用户
Dec 06 PHP
自动把纯文本转换成Web页面的php代码
Aug 27 PHP
CentOS下PHP7的编译安装及MySQL的支持和一些常见问题的解决办法
Dec 17 PHP
PHP连接MSSQL方法汇总
Feb 05 PHP
PHP批量去除BOM头内容信息代码
Mar 11 PHP
PHP数学运算函数大汇总(经典值得收藏)
Apr 01 PHP
php生成酷炫的四个字符验证码
Apr 22 PHP
PHP 文件锁与进程锁的使用示例
Aug 07 PHP
php实现与python进行socket通信的方法示例
Aug 30 PHP
php微信公众号开发之微信企业付款给个人
Oct 04 PHP
PHP实现的数据对象映射模式详解
Mar 20 PHP
PHP常见的几种攻击方式实例小结
Apr 29 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获得flv视频长度的实例代码
2017/10/26 PHP
php接口实现拖拽排序功能
2018/04/23 PHP
PHP语言对接抖音快手小红书视频/图片去水印API接口源码
2020/08/11 PHP
JS与框架页的操作代码
2010/01/17 Javascript
理清apply(),call()的区别和关系
2011/08/14 Javascript
jquery使用淘宝接口跨域查询手机号码归属地实例
2013/11/28 Javascript
基于BootStrap Metronic开发框架经验小结【二】列表分页处理和插件JSTree的使用
2016/05/12 Javascript
BootStrap智能表单实战系列(六)表单编辑页面的数据绑定
2016/06/13 Javascript
Web程序员必备的7个JavaScript函数
2016/06/14 Javascript
基于jQuery实现的幻灯图片切换
2016/12/02 Javascript
详解vue项目打包后通过百度的BAE发布到网上的流程
2018/03/05 Javascript
vue + vuex todolist的实现示例代码
2018/03/09 Javascript
基于js中的存储键值对以及注意事项介绍
2018/03/30 Javascript
浅谈Redux中间件的实践
2018/07/27 Javascript
js+html实现周岁年龄计算器
2019/06/25 Javascript
JavaScript 斐波那契数列 倒序输出 输出100以内的质数代码实例
2019/09/11 Javascript
js键盘事件实现人物的行走
2020/01/17 Javascript
[05:46]DOTA2英雄梦之声_第18期_陈
2014/06/20 DOTA
[01:27:30]LGD vs Newbee 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/19 DOTA
python技能之数据导出excel的实例代码
2017/08/11 Python
Python爬虫常用库的安装及其环境配置
2018/09/19 Python
python使用正则表达式来获取文件名的前缀方法
2018/10/21 Python
python用post访问restful服务接口的方法
2018/12/07 Python
python函数的万能参数传参详解
2019/07/26 Python
移动端HTML5实现文件上传功能【附代码】
2016/03/25 HTML / CSS
Magee 1866官网:Donegal粗花呢外套和大衣专家
2019/11/01 全球购物
德国在线香料制造商:Gewürzland
2020/03/10 全球购物
俄罗斯领先的移动和数字设备在线商店:Svyaznoy.ru
2020/12/21 全球购物
三八红旗集体先进事迹材料
2014/05/22 职场文书
爱岗敬业事迹材料
2014/12/24 职场文书
2015年安全生产月活动总结
2015/03/26 职场文书
地道战观后感500字
2015/06/04 职场文书
毕业典礼致辞
2015/07/29 职场文书
数据库的高级查询六:表连接查询:外连接(左外连接,右外连接,UNION关键字,连接中ON与WHERE的不同)
2021/04/05 MySQL
python 实现两个变量值进行交换的n种操作
2021/06/02 Python
详解java如何集成swagger组件
2021/06/21 Java/Android