浅谈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 相关文章推荐
用文本文件实现的动态实时发布新闻的程序
Oct 09 PHP
完美实现GIF动画缩略图的php代码
Jan 02 PHP
php数组函数序列之each() - 获取数组当前内部指针所指向元素的键名和键值,并将指针移到下一位
Oct 31 PHP
PHP实现邮件群发的源码
Jun 18 PHP
ThinkPHP自动完成中使用函数与回调方法实例
Nov 29 PHP
php统计数组元素个数的方法
Jul 02 PHP
php随机显示指定文件夹下图片的方法
Jul 13 PHP
如何使用Gitblog和Markdown建自己的博客
Jul 31 PHP
PHP正则表达式之捕获组与非捕获组
Nov 06 PHP
PHP图像识别技术原理与实现
Oct 27 PHP
php获取微信共享收货地址的方法
Dec 21 PHP
ThinkPHP3.2.3框架邮件发送功能图文实例详解
Apr 23 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
全国FM电台频率大全 - 15 山东省
2020/03/11 无线电
如何利用php array_multisort函数 对数据库结果进行复杂排序
2013/06/08 PHP
PHP输出九九乘法表代码实例
2015/03/27 PHP
yii2项目实战之restful api授权验证详解
2017/05/20 PHP
PHP实现上传图片到数据库并显示输出的方法
2018/05/31 PHP
iframe实用操作锦集
2014/04/22 Javascript
Express实现前端后端通信上传图片之存储数据库(mysql)傻瓜式教程(二)
2015/12/10 Javascript
Node.js 应用跑得更快 10 个技巧
2016/04/03 Javascript
浅析JS获取url中的参数实例代码
2016/06/14 Javascript
Angular中的$watch、$watchGroup、$watchCollection
2017/06/25 Javascript
详谈innerHTML innerText的使用和区别
2017/08/18 Javascript
bootstrap-table组合表头的实现方法
2017/09/07 Javascript
vue中使用cropperjs的方法
2018/03/01 Javascript
vue 组件高级用法实例详解
2018/04/11 Javascript
js实现单元格拖拽效果
2020/02/10 Javascript
JavaScript常用工具函数汇总(浏览器环境)
2020/09/17 Javascript
使用Python导出Excel图表以及导出为图片的方法
2015/11/07 Python
Python中pandas dataframe删除一行或一列:drop函数详解
2018/07/03 Python
python文件操作之批量修改文件后缀名的方法
2018/08/10 Python
Opencv实现抠图背景图替换功能
2019/05/21 Python
python实现中文文本分句的例子
2019/07/15 Python
Django缓存系统实现过程解析
2019/08/02 Python
关于python字符串方法分类详解
2019/08/20 Python
Pytorch Tensor基本数学运算详解
2019/12/30 Python
基于TensorFlow中自定义梯度的2种方式
2020/02/04 Python
浅谈Django前端后端值传递问题
2020/07/15 Python
逼真的HTML5树叶飘落动画
2016/03/01 HTML / CSS
RetroStage德国:复古服装
2019/02/03 全球购物
工程专业应届生求职信
2014/02/19 职场文书
有多年工作经验的自我评价
2014/03/02 职场文书
活动总结怎么写
2014/04/28 职场文书
论文指导教师评语
2014/04/28 职场文书
小学生勤俭节约演讲稿
2014/08/28 职场文书
投标文件签署授权委托书范本
2014/10/12 职场文书
小学校长个人总结
2015/03/03 职场文书
在python中读取和写入CSV文件详情
2022/06/28 Python