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调用Oracle存储过程
Oct 09 PHP
来自PHP.NET的入门教程
Oct 09 PHP
PHP中isset()和unset()函数的用法小结
Mar 11 PHP
浅析php单例模式
Nov 25 PHP
php实现使用正则将文本中的网址转换成链接标签
Dec 03 PHP
PHP学习笔记(三):数据类型转换与常量介绍
Apr 17 PHP
ThinkPHP自定义函数解决模板标签加减运算的方法
Jul 03 PHP
摘自织梦CMS的HTTP文件下载类
Aug 08 PHP
详解php 使用Callable Closure强制指定回调类型
Oct 26 PHP
PHP实现微信提现(企业付款到零钱)
Aug 01 PHP
thinkphp3.2框架中where条件查询用法总结
Aug 13 PHP
Laravel监听数据库访问,打印SQL的例子
Oct 24 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
实时抓取YAHOO股票报价的代码
2006/10/09 PHP
PHP cron中的批处理
2008/09/16 PHP
linux php mysql数据库备份实现代码
2009/03/10 PHP
Zend Framework入门教程之Zend_Registry组件用法详解
2016/12/09 PHP
Thinkphp5框架实现获取数据库数据到视图的方法
2019/08/14 PHP
Laravel实现通过blade模板引擎渲染视图
2019/10/25 PHP
javascript操作文本框readOnly
2007/05/15 Javascript
JavaScript开发规范要求(规范化代码)
2010/08/16 Javascript
初学js 新节点的创建 删除 的步骤
2011/07/04 Javascript
关于IE BUG与字符串截取substr的解决办法
2013/04/10 Javascript
零基础搭建Node.js、Express、Ejs、Mongodb服务器及应用开发入门
2014/12/20 Javascript
通过伪协议解决父页面与iframe页面通信的问题
2015/04/05 Javascript
微信小程序 ES6Promise.all批量上传文件实现代码
2017/04/14 Javascript
JS正则表达式完美实现身份证校验功能
2017/10/18 Javascript
JavaScript实现三级级联特效
2017/11/05 Javascript
windows系统下更新nodejs版本的方案
2017/11/24 NodeJs
React key值的作用和使用详解
2018/08/23 Javascript
Vue函数式组件-你值得拥有
2019/05/09 Javascript
Vue 同步异步存值取值实现案例
2020/08/05 Javascript
js+canvas绘制图形验证码
2020/09/21 Javascript
vue 判断两个时间插件结束时间必选大于开始时间的代码
2020/11/04 Javascript
Python中urllib2模块的8个使用细节分享
2015/01/01 Python
react+django清除浏览器缓存的几种方法小结
2019/07/17 Python
Django 重写用户模型的实现
2019/07/29 Python
Pytorch技巧:DataLoader的collate_fn参数使用详解
2020/01/08 Python
Cotton On香港网站:澳洲时装连锁品牌
2018/11/01 全球购物
法国高保真音响和家庭影院商店:Son Video
2019/04/26 全球购物
巴塞罗那观光通票:Barcelona Pass
2019/10/30 全球购物
售后服务承诺书范文
2014/03/26 职场文书
创业培训计划书
2014/05/03 职场文书
小学生勤俭节约演讲稿
2014/08/28 职场文书
生产现场禁烟通知
2015/04/23 职场文书
建国大业观后感600字
2015/06/01 职场文书
爱的教育读书笔记
2015/06/26 职场文书
mysql连接查询中and与where的区别浅析
2021/07/01 MySQL
Redis实现订单过期删除的方法步骤
2022/06/05 Redis