浅谈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 相关文章推荐
WINDOWS 2000下使用ISAPI方式安装PHP
Sep 05 PHP
文件上传的实现
Oct 09 PHP
BBS(php &amp; mysql)完整版(一)
Oct 09 PHP
php imagecreatetruecolor 创建高清和透明图片代码小结
May 15 PHP
一个PHP验证码类代码分享(已封装成类)
Jul 17 PHP
浅谈php serialize()与unserialize()的用法
Jun 05 PHP
解析PHP留言本模块主要功能的函数说明(代码可实现)
Jun 25 PHP
深入浅析PHP7.0新特征(五大新特征)
Oct 29 PHP
优化WordPress中文章与评论的时间显示
Jan 12 PHP
PHP检测数据类型的几种方法(总结)
Mar 04 PHP
PHP中的访问修饰符简单比较
Feb 02 PHP
PHP addAttribute()函数讲解
Feb 03 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
Ubuntu下安装PHP的mongodb扩展操作命令
2015/07/04 PHP
Yii控制器中操作视图js的方法
2016/07/04 PHP
PHP长连接实现与使用方法详解
2018/02/11 PHP
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
基于Jquery实现的一个图片滚动切换
2012/06/21 Javascript
Node.js文件操作详解
2014/08/16 Javascript
javascript中字符串拼接详解
2014/09/26 Javascript
Jquery中offset()和position()的区别分析
2015/02/05 Javascript
javascript三元运算符用法实例
2015/04/16 Javascript
jquery validate demo 基础
2015/10/29 Javascript
举例说明如何为JavaScript的方法参数设置默认值
2015/11/17 Javascript
底部悬浮通栏可以关闭广告位的实现方法
2016/06/01 Javascript
JavaScript浮点数及运算精度调整详解
2016/10/21 Javascript
js实现百度搜索提示框
2017/02/05 Javascript
Bootstrap表格使用方法详解
2017/02/17 Javascript
vue解决跨域路由冲突问题思路解析
2017/11/03 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
extract-text-webpack-plugin用法详解
2019/02/14 Javascript
使用webpack搭建vue项目及注意事项
2019/06/10 Javascript
jQuery子选择器与可见性选择器实例分析
2019/06/28 jQuery
微信小程序使用Vant Weapp组件库的方法步骤
2019/08/01 Javascript
Vue实现腾讯云点播视频上传功能的实现代码
2020/08/17 Javascript
基于Cesium绘制抛物弧线
2020/11/18 Javascript
[05:17]DOTA2誓师:今天我们在这里 明天TI4等我!
2014/03/26 DOTA
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
Python根据当前日期取去年同星期日期
2019/04/14 Python
python数据持久存储 pickle模块的基本使用方法解析
2019/08/30 Python
Python实现FTP文件定时自动下载的步骤
2020/12/19 Python
用HTML5制作一个简单的弹力球游戏
2015/05/12 HTML / CSS
朗仕(Lab series)英国官网:雅诗兰黛集团男士专属护肤品牌
2017/11/28 全球购物
企业后勤岗位职责
2014/02/28 职场文书
求职个人评价范文
2014/04/09 职场文书
党建工作汇报材料
2014/12/24 职场文书
2016北大自主招生自荐信模板
2016/01/28 职场文书
诗词赏析-(浣溪沙)
2019/08/13 职场文书
详解MySQL主从复制及读写分离
2021/05/07 MySQL