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支持页面回退的两种方法
Jan 10 PHP
php 如何获取数组第一个值
Aug 06 PHP
php用正则表达式匹配URL的简单方法
Nov 12 PHP
php修改指定文件后缀的方法
Sep 11 PHP
php无限极分类递归排序实现方法
Nov 11 PHP
php生成年月日下载列表的方法
Apr 24 PHP
[原创]ThinkPHP中SHOW_RUN_TIME不能正常显示运行时间的解决方法
Oct 10 PHP
PHP简单的MVC框架实现方法
Dec 01 PHP
thinkphp,onethink和thinkox中验证码不显示的解决方法分析
Jun 06 PHP
php写app接口并返回json数据的实例(分享)
May 20 PHP
PHP商品秒杀问题解决方案实例详解【mysql与redis】
Jul 22 PHP
Laravel Eloquent分表方法并使用模型关联的实现
Nov 25 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 批量替换html标签的实例代码
2013/11/26 PHP
php redis实现文章发布系统(用户投票系统)
2017/03/04 PHP
PHP实现的贪婪算法实例
2017/10/17 PHP
基于Jquery的简单&amp;简陋Tabs插件代码
2010/02/09 Javascript
jquery数据验证插件(自制,简单,练手)实例代码
2013/10/24 Javascript
一个JavaScript获取元素当前高度的实例
2014/10/29 Javascript
常见的jQuery选择器汇总
2014/11/24 Javascript
用window.onerror捕获并上报Js错误的方法
2016/01/27 Javascript
Javascript数组Array方法解读
2016/03/13 Javascript
JavaScript正则表达式实例详解
2016/10/16 Javascript
Javascript基础回顾之(三) js面向对象
2017/01/31 Javascript
jQuery动态添加li标签并添加属性和绑定事件方法
2018/02/24 jQuery
Vue2.0 实现移动端图片上传功能
2018/05/30 Javascript
qrcode生成二维码微信长按无法识别问题的解决
2019/04/04 Javascript
webpack5 联邦模块介绍详解
2020/07/08 Javascript
Python实现MySQL操作的方法小结【安装,连接,增删改查等】
2017/07/12 Python
python爬虫爬取淘宝商品信息
2018/02/23 Python
Python实现输入二叉树的先序和中序遍历,再输出后序遍历操作示例
2018/07/27 Python
python添加菜单图文讲解
2019/06/04 Python
用Python抢火车票的简单小程序实现解析
2019/08/14 Python
解决python Jupyter不能导入外部包问题
2020/04/15 Python
Pandas之缺失数据的实现
2021/01/06 Python
详解win10下pytorch-gpu安装以及CUDA详细安装过程
2021/01/28 Python
丝芙兰巴西官方商城:SEPHORA巴西
2016/10/31 全球购物
Skyscanner英国:苏格兰的全球三大领先航班搜索服务之一
2017/11/09 全球购物
Ray-Ban雷朋西班牙官网:全球领先的太阳眼镜品牌
2018/11/28 全球购物
传统软件工程与面向对象的软件工程有什么区别
2012/05/31 面试题
应届生会计求职信
2013/11/11 职场文书
党员自我评议对照检查材料
2014/09/27 职场文书
政协委员个人总结
2015/03/03 职场文书
道歉的话语大全
2015/05/12 职场文书
经济纠纷起诉状
2015/05/20 职场文书
关于实现中国梦的心得体会
2016/01/05 职场文书
分享15个Webpack实用的插件!!!
2021/03/31 Javascript
Python中异常处理用法
2021/11/27 Python