浅谈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
php获得当前的脚本网址
Dec 10 PHP
php中++i 与 i++ 的区别
Aug 08 PHP
PHP连接局域网MYSQL数据库的简单实例
Aug 26 PHP
phpstrom使用xdebug配置方法
Dec 17 PHP
yii2.0使用Plupload实现带缩放功能的多图上传
Dec 22 PHP
php 指定范围内多个随机数代码实例
Jul 18 PHP
PHP图形计数器程序显示网站用户浏览量
Jul 20 PHP
smarty模板数学运算示例
Dec 11 PHP
Yii框架通过请求组件处理get,post请求的方法分析
Sep 03 PHP
PHP实现的AES 128位加密算法示例
Sep 16 PHP
解析laravel使用workerman用户交互、服务器交互
Apr 28 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
Smarty结合Ajax实现无刷新留言本实例
2007/01/02 PHP
PHP中MD5函数使用实例代码
2008/06/07 PHP
C# Assembly类访问程序集信息
2009/06/13 PHP
destoon整合UCenter图文教程
2014/06/21 PHP
用php守护另一个php进程的例子
2015/02/13 PHP
thinkPHP下的widget扩展用法实例分析
2015/12/26 PHP
Laravel中encrypt和decrypt的实现方法
2017/09/24 PHP
laravel框架查询数据集转为数组的两种方法
2019/10/10 PHP
addRule在firefox下的兼容写法
2006/11/30 Javascript
网页自动跳转代码收集
2009/09/27 Javascript
关于this和self的使用说明
2010/08/01 Javascript
jquery实现tr元素的上下移动示例代码
2013/12/20 Javascript
javascript从image转换为base64位编码的String
2014/07/29 Javascript
jQuery中extend函数的实现原理详解
2015/02/03 Javascript
学习JavaScript设计模式之模板方法模式
2016/01/20 Javascript
浅谈Vue-cli 命令行工具分析
2017/11/22 Javascript
JavaScript读写二进制数据的方法详解
2018/09/09 Javascript
生产制造追溯系统之在线打印功能
2019/06/03 Javascript
Vue.js路由实现选项卡简单实例
2019/07/24 Javascript
在Vue项目中用fullcalendar制作日程表的示例代码
2019/08/04 Javascript
vue使用高德地图点击下钻上浮效果的实现思路
2019/10/12 Javascript
在vue中使用cookie记住用户上次选择的实例(本次例子中为下拉框)
2020/09/11 Javascript
Python def函数的定义、使用及参数传递实现代码
2014/08/10 Python
python实现无证书加密解密实例
2014/10/27 Python
python实现弹跳小球
2019/05/13 Python
python安装scipy的步骤解析
2019/09/28 Python
python二进制读写及特殊码同步实现详解
2019/10/11 Python
Django多进程滚动日志问题解决方案
2019/12/17 Python
pytorch1.0中torch.nn.Conv2d用法详解
2020/01/10 Python
Python中的X[:,0]、X[:,1]、X[:,:,0]、X[:,:,1]、X[:,m:n]和X[:,:,m:n]
2020/02/13 Python
中国双语服务优势的在线购票及活动平台:247tickets
2018/10/26 全球购物
接口可以包含哪些成员
2012/09/30 面试题
写一个函数,要求输入一个字符串和一个字符长度,对该字符串进行分隔
2015/07/30 面试题
《将心比心》教学反思
2014/04/08 职场文书
校长一岗双责责任书
2015/05/09 职场文书
pandas中pd.groupby()的用法详解
2022/06/16 Python