浅谈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 相关文章推荐
用Socket发送电子邮件
Oct 09 PHP
用PHP动态生成虚拟现实VRML网页
Oct 09 PHP
php 删除cookie和浏览器重定向
Mar 16 PHP
关于svn冲突的解决方法
Jun 21 PHP
[原创]PHP实现逐行删除文件右侧空格的方法
Dec 25 PHP
thinkphp3.2.3 分页代码分享
Jul 28 PHP
示例详解Laravel重置密码代码重构
Aug 10 PHP
PHP中的use关键字及文件的加载详解
Nov 28 PHP
php图片合成方法(多张图片合成一张)
Nov 25 PHP
浅谈PHPANALYSIS提取关键字
Mar 08 PHP
Laravel框架实现简单的学生信息管理平台案例
May 07 PHP
Laravel开启跨域请求的方法
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
人族 TERRAN 概述
2020/03/14 星际争霸
国王的咖啡这么大来头,名字的由来是什么
2021/03/03 咖啡文化
php 生成唯一id的几种解决方法
2013/03/08 PHP
PHP删除HTMl标签的三种解决方法
2013/06/30 PHP
PHP错误Cannot use object of type stdClass as array in错误的解决办法
2014/06/12 PHP
Jquery 学习笔记(一)
2009/10/13 Javascript
JavaScript面向对象之静态与非静态类
2010/02/03 Javascript
批量实现面向对象的实例代码
2013/07/01 Javascript
jquery 模板的应用示例
2013/11/12 Javascript
js中的布尔运算符使用介绍
2013/11/20 Javascript
js中typeof的用法汇总
2013/12/12 Javascript
js获取url参数代码实例分享(JS操作URL)
2013/12/13 Javascript
动态读取JSON解析键值对的方法
2014/06/03 Javascript
理解javascript回调函数
2014/12/28 Javascript
javascript实现点击提交按钮后显示loading的方法
2015/07/03 Javascript
React实现双向绑定示例代码
2016/09/19 Javascript
Angular2中select用法之设置默认值与事件详解
2017/05/07 Javascript
详解Vue双向数据绑定原理解析
2017/09/11 Javascript
Vue.js组件通信的几种姿势
2017/10/23 Javascript
Three.js加载外部模型的教程详解
2017/11/10 Javascript
vue项目部署上线遇到的问题及解决方法
2018/06/10 Javascript
vue 配置多页面应用的示例代码
2018/10/22 Javascript
layer.open回调获取弹出层参数的实现方法
2019/09/10 Javascript
python WindowsError的错误代码详解
2017/07/23 Python
运行django项目指定IP和端口的方法
2018/05/14 Python
Python中的Cookie模块如何使用
2020/06/04 Python
印尼值得信赖的在线交易网站:Bukalapak
2019/03/11 全球购物
澳大利亚鞋仓库:Shoe Warehouse
2019/07/25 全球购物
linux系统都有哪些运行级别
2012/04/15 面试题
教你怎样写好自我评价
2013/10/05 职场文书
竞选学生会主席演讲稿
2014/04/24 职场文书
新婚姻法离婚协议书范文
2014/11/30 职场文书
2015小学五年级班主任工作总结
2015/05/21 职场文书
广告文案的撰写技巧(实用干货)
2019/08/23 职场文书
职场:企业印章管理制度(模板)
2019/10/18 职场文书
 分享一个Python 遇到数据库超好用的模块
2022/04/06 Python