浅谈PHP正则中的捕获组与非捕获组


Posted in PHP onJuly 18, 2016

今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同时也希望有大神和细心的学习者找到我理解中出现的问题。

什么是捕获组

我们先看一下PHP的正则匹配函数

int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags = 0 [, int $offset = 0 ]]] )

前面两项是我们常用的,$pattern是正则匹配模式,$string是要匹配的字符串。

array &$match,它是一个数组,&表示匹配出来的结果会被写入$match中。

int $flags 如果传递了这个标记, 对于每一个出现的匹配返回时会附加字符串偏移量(相对于目标字符串的)。

int $offset 用于指定从目标字符串的某个未知开始搜索(单位是字节)。

我们主要看一下$match的值里会有什么:

$mode = '/a=(\d+)b=(\d+)c=(\d+)/';

$str='**a=4b=98c=56**';

$res=preg_match($mode,$str,$match);

var_dump($match);

结果如下:

array (size=4)
=> string 'a=4b=98c=56' (length=11)
=> string '4' (length=1)
=> string '98' (length=2)
=> string '56' (length=2)

现在我们知道了什么是捕获组,捕获组是正则表达示中以()括起来的部分,每一对()是一个捕获组。

PHP会为它编号,从1开始。至于为什么会从1开始,那是因为PHP把匹配到的完整字符串编号为0。

如果有多个括号或嵌套括号,按左边括号出现的顺序来进行编号,如图:

浅谈PHP正则中的捕获组与非捕获组

按图中的匹配模式匹配时,捕获组的123号分别是红绿蓝。

捕获组的忽略与命名

我们还可以阻止PHP为匹配组的编号:在匹配组中模式前加  ?:

$mode = '/a=(\d+)b=(?:\d+)c=(\d+)/';

这样,匹配结果就会变成:

array (size=3)
=> string 'a=4b=98c=56' (length=11)
=> string '4' (length=1)
=> string '56' (length=2)

当然,我们也可以在括号的内部为它给它独特的名字。

命名子组可以接受(?<name>), (?'name') 以及(?P<name>)语法. 之前版本仅接受(?P<name>)语法.

例如:$mode = '/a=(\d+)b=(?P<sec>\d+)c=(\d+)/';

使用时结果为:

array (size=5)
=> string 'a=4b=98c=56' (length=11)
=> string '4' (length=1)

 'sec' => string '98' (length=2)
=> string '98' (length=2)
=> string '56' (length=2)

在保留索引数组的同时,加上一个关联项,key值为捕获组名。

捕获组的反向引用

我们在用preg_replace()函数进行正则替换时,我们还可以使用 \n 或 $n 来引用第n个捕获组.

$mode = '/a=(\d+)b=(\d+)c=(\d+)/';

$str='**a=4b=98c=56**';

$rp='\1/$2/\3/';

echo preg_replace($mode,$rp,$str);//**4/98/56/**

\1表示捕获组1(4),$2为捕获组2(98),\3为捕获组3(56)。

非捕获组的用法:

为什么称为非捕获组呢?那是因为它们有捕获组的特性,在匹配模式的()中,但是匹配时,PHP不会为它们编组,它们只会影响匹配结果,并不作为结果输出。

/d(?=xxx)    匹配"后面是xxx的一个数字"。

注意格式:只能放在匹配模式字符串之后

例如:

$pattern='/\d(?=abc)/';

$str="ab36abc8eg";

$res=preg_match($pattern,$str,$match);

var_dump($match);//6

匹配的6,因为只有它作为一个数字,后面还有abc。

(?<=xxx) /d 匹配"前面是xxx的一个数字"

注意格式:只能放在匹配模式字符串之前

例如:

$pattern='/(?<=abc)\d/';

$str="ab36abc8eg";

$res=preg_match($pattern,$str,$match);

var_dump($match);//8

匹配的8,因为只有它作为一个数字,后面还有abc。

与(?=xxx)  (?<=xxx)相对的是(?!=xxx)  (?<!=xxx) 它们在=前加了非运算符 “!”

它表示前面/后面不是xxx的字符串,这里就不再举例了。

以上这篇浅谈PHP正则中的捕获组与非捕获组就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
php抓即时股票信息
Oct 09 PHP
完美解决dedecms中的[html][/html]和[code][/code]问题
Mar 20 PHP
有关PHP中MVC的开发经验分享
May 17 PHP
基于python发送邮件的乱码问题的解决办法
Apr 25 PHP
基于curl数据采集之单页面采集函数get_html的使用
Apr 28 PHP
深入php 正则表达式的学习探讨
Jun 06 PHP
PHP GD库生成图像的几个函数总结
Nov 19 PHP
PHP简单处理表单输入的特殊字符的方法
Feb 03 PHP
PHP内存缓存功能memcached示例
Oct 19 PHP
PHP正则验证字符串是否为数字的两种方法并附常用正则
Feb 27 PHP
PHP实现的策略模式示例
Mar 20 PHP
Thinkphp5.0框架视图view的循环标签用法示例
Oct 12 PHP
Yii2.0表关联查询实例分析
Jul 18 #PHP
php 实现301重定向跳转实例代码
Jul 18 #PHP
PHP的openssl加密扩展使用小结(推荐)
Jul 18 #PHP
PHP多进程编程总结(推荐)
Jul 18 #PHP
php 指定范围内多个随机数代码实例
Jul 18 #PHP
php 解决substr()截取中文字符乱码问题
Jul 18 #PHP
Yii2中cookie用法示例分析
Jul 18 #PHP
You might like
学习使用PHP数组
2006/10/09 PHP
Codeigniter中禁止A Database Error Occurred错误提示的方法
2014/06/12 PHP
PHP自定义函数实现格式化秒的方法
2016/09/14 PHP
php使用高斯算法实现图片的模糊处理功能示例
2016/11/11 PHP
学习YUI.Ext 第七天--关于View&amp;JSONView
2007/03/10 Javascript
javascript 关于# 和 void的区别分析
2009/10/26 Javascript
JS构建页面的DOM节点结构的实现代码
2011/12/09 Javascript
基于IE下ul li 互相嵌套时的bug,排查,解决过程以及心得介绍
2013/05/07 Javascript
JS字符串截取函数实例
2013/12/27 Javascript
iframe窗口高度自适应的又一个巧妙实现思路
2014/04/04 Javascript
详解微信小程序开发之——wx.showToast(OBJECT)的使用
2017/01/18 Javascript
js实现消息滚动效果
2017/01/18 Javascript
bootstrap组件之导航组件使用方法
2017/01/19 Javascript
微信小程序图片选择、上传到服务器、预览(PHP)实现实例
2017/05/11 Javascript
javaScript实现滚动条事件详解
2020/03/24 Javascript
微信小程序实现发送验证码按钮效果
2018/12/20 Javascript
Node.JS发送http请求批量检查文件中的网页地址、服务是否有效可用
2019/11/20 Javascript
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
详解JavaScript中的链式调用
2020/11/27 Javascript
[41:08]2014 DOTA2国际邀请赛中国区预选赛 HGT VS NE
2014/05/22 DOTA
[52:40]完美世界DOTA2联赛PWL S2 Magma vs GXR 第一场 11.29
2020/12/02 DOTA
Python简单实现阿拉伯数字和罗马数字的互相转换功能示例
2018/04/17 Python
Python 实现王者荣耀中的敏感词过滤示例
2019/01/21 Python
基于PyQt4和PySide实现输入对话框效果
2019/02/27 Python
Python如何读取文件中图片格式
2020/01/13 Python
Django认证系统user对象实现过程解析
2020/03/02 Python
Django通过设置CORS解决跨域问题
2020/11/26 Python
分解成质因数(如435234=251*17*17*3*2,据说是华为笔试题)
2014/07/16 面试题
荷叶圆圆教学反思
2014/02/01 职场文书
财务总监管理职责范文
2014/03/09 职场文书
服务之星事迹材料
2014/05/03 职场文书
工作保证书
2015/01/17 职场文书
小学国庆节活动总结
2015/03/23 职场文书
红色故事汇观后感
2015/06/18 职场文书
2019年大学毕业生个人自我鉴定范文大全
2019/03/21 职场文书
SQL Server 忘记密码以及重新添加新账号
2022/04/26 SQL Server