浅谈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 魔术函数使用说明
Feb 21 PHP
setcookie中Cannot modify header information-headers already sent by错误的解决方法详解
May 08 PHP
thinkphp在模型中自动完成session赋值示例代码
Sep 09 PHP
php ImageMagick windows下安装教程
Jan 26 PHP
php图片添加水印例子
Jul 20 PHP
PHP实现微信JS-SDK接口选择相册及拍照并上传的方法
Dec 05 PHP
PHPMailer发送邮件
Dec 28 PHP
利用PHP访问MySql数据库的逻辑操作以及增删改查的实例讲解
Aug 30 PHP
phpstudy的php版本自由修改的方法
Oct 18 PHP
PHP设计模式之原型模式定义与用法详解
Apr 03 PHP
Laravel框架路由设置与使用示例
Jun 12 PHP
Laravel 5.4前后台分离,通过不同的二级域名访问方法
Oct 13 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 json转换成数组形式代码分享
2014/11/10 PHP
Yii2中使用join、joinwith多表关联查询
2016/06/30 PHP
iOS自定义提示弹出框实现类似UIAlertView的效果
2016/11/16 PHP
php实现文章评论系统
2019/02/18 PHP
详解PHP多个进程配合redis的有序集合实现大文件去重
2019/03/06 PHP
WordPress JQuery处理沙发头像
2009/06/22 Javascript
jQuery阻止事件冒泡具体实现
2013/10/11 Javascript
浅谈javascript语法和定时函数
2015/05/03 Javascript
JQuery中解决重复动画的方法
2016/10/17 Javascript
Vue.js学习之过滤器详解
2017/01/22 Javascript
jQuery实现弹窗居中效果类似alert()
2017/02/27 Javascript
JS表格组件神器bootstrap table使用指南详解
2017/04/12 Javascript
浅谈ES6 模板字符串的具体使用方法
2017/11/07 Javascript
微信小程序使用audio组件播放音乐功能示例【附源码下载】
2017/12/08 Javascript
使用Electron构建React+Webpack桌面应用的方法
2017/12/15 Javascript
浅谈vuejs实现数据驱动视图原理
2018/02/23 Javascript
vue slot 在子组件中显示父组件传递的模板
2018/03/02 Javascript
使用vuepress搭建静态博客的示例代码
2019/02/14 Javascript
vue v-for 使用问题整理小结
2019/08/04 Javascript
JS+HTML实现自定义上传图片按钮并显示图片功能的方法分析
2020/02/12 Javascript
[05:20]2018DOTA2亚洲邀请赛主赛事第三日战况回顾 LGD率先挺进胜者组决赛
2018/04/06 DOTA
python类型强制转换long to int的代码
2013/02/10 Python
老生常谈进程线程协程那些事儿
2017/07/24 Python
使用Python实现windows下的抓包与解析
2018/01/15 Python
使用python将图片按标签分入不同文件夹的方法
2018/12/08 Python
Python使用pyshp库读取shapefile信息的方法
2018/12/29 Python
Python对Tornado请求与响应的数据处理
2020/02/12 Python
CSS3下的渐变文字效果实现示例
2018/03/02 HTML / CSS
介绍一下如何利用路径遍历进行攻击及如何防范
2014/01/19 面试题
招商专员岗位职责
2014/02/08 职场文书
党员违纪检讨书
2014/02/18 职场文书
培训通知书模板
2015/04/17 职场文书
销售人员管理制度
2015/08/06 职场文书
Vue中Object.assign清空数据报错的解决方案
2022/03/03 Vue.js
Pycharm远程调试和MySQL数据库授权问题
2022/03/18 MySQL
python中filter,map,reduce的作用
2022/06/10 Python