浅谈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分页函数
Jul 08 PHP
php统计文件大小,以GB、MB、KB、B输出
May 29 PHP
php在项目中寻找代码的坏味道(综艺命名)
Jul 19 PHP
php字符串截取的简单方法
Jul 04 PHP
PHP $_FILES中error返回值详解
Jan 30 PHP
php的ajax简单实例
Feb 27 PHP
纯PHP生成的一个树叶图片画图例子
Apr 16 PHP
php获取twitter最新消息的方法
Apr 14 PHP
php fseek函数读取大文件两种方法
Oct 12 PHP
关于PHP内置的字符串处理函数详解
Feb 04 PHP
php获得刚插入数据的id 的几种方法总结
May 31 PHP
PHP抽象类和接口用法实例详解
Jul 20 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
Memcache 在PHP中的使用技巧
2010/02/08 PHP
php中突破基于HTTP_REFERER的防盗链措施(stream_context_create)
2011/03/29 PHP
jQuery 源码分析笔记
2011/05/25 PHP
PHP微框架Dispatch简介
2014/06/12 PHP
PHP数组排序之sort、asort与ksort用法实例
2014/09/08 PHP
PHP自带ZIP压缩、解压缩类ZipArchiv使用指南
2015/03/03 PHP
[原创]php正则删除img标签的方法示例
2017/05/27 PHP
Laravel框架Eloquent ORM删除数据操作示例
2019/12/03 PHP
ext实现完整的登录代码
2008/08/08 Javascript
jquery ajax请求方式与提示用户正在处理请稍等
2014/09/01 Javascript
js实现单张图片平移切换效果
2017/10/11 Javascript
Node做中转服务器转发接口
2017/10/18 Javascript
高性能的javascript之加载顺序与执行原理篇
2018/01/14 Javascript
详解如何制作并发布一个vue的组件的npm包
2018/11/10 Javascript
vue+Element-ui实现分页效果实例代码详解
2018/12/10 Javascript
js绘制一条直线并旋转45度
2020/08/21 Javascript
解决Antd Table组件表头不对齐的问题
2020/10/27 Javascript
[01:02:20]Mineski vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.15
2019/08/16 DOTA
在Python下使用Txt2Html实现网页过滤代理的教程
2015/04/11 Python
Python中functools模块函数解析
2017/03/12 Python
python 统计代码行数简单实例
2017/05/04 Python
python3+django2开发一个简单的人员管理系统过程详解
2019/07/23 Python
Python生成个性签名图片获取GUI过程解析
2019/12/16 Python
解决Pycharm中恢复被exclude的项目问题(pycharm source root)
2020/02/14 Python
解决Tensorboard可视化错误:不显示数据 No scalar data was found
2020/02/15 Python
Keras模型转成tensorflow的.pb操作
2020/07/06 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
高尔夫球鞋、服装、手套和装备:FootJoy
2018/12/15 全球购物
Orvis官网:自1856年以来,优质服装、飞钓装备等
2018/12/17 全球购物
家长给小学生的评语
2014/01/30 职场文书
院党委组织查摆问题对照检查材料思想汇报2014
2014/10/08 职场文书
银行授权委托书样本
2014/10/13 职场文书
2015年综治维稳工作总结
2015/04/07 职场文书
如何制定销售人员薪酬制度?
2019/07/09 职场文书
MySQL GRANT用户授权的实现
2021/06/18 MySQL
vue elementUI批量上传文件
2022/04/26 Vue.js