浅谈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 相关文章推荐
IStream与TStream之间的相互转换
Aug 01 PHP
php中比较简单的导入phpmyadmin生成的sql文件的方法
Jun 28 PHP
php空间不支持socket但支持curl时recaptcha的用法
Nov 07 PHP
解析php函数method_exists()与is_callable()的区别
Jun 21 PHP
codeigniter使用技巧批量插入数据实例方法分享
Dec 31 PHP
php在数据库抽象层简单使用PDO的方法
Nov 03 PHP
开启PHP的伪静态模式
Dec 31 PHP
Yii中表单用法实例详解
Jan 05 PHP
PHP结合Mysql数据库实现留言板功能
Mar 04 PHP
php导出csv文件,可导出前导0实例代码
Nov 16 PHP
php获取给定日期相差天数的方法分析
Feb 20 PHP
laravel 5.1下php artisan migrate的使用注意事项总结
Jun 07 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中使用key,value,current,next和prev函数遍历数组的方法
2015/03/17 PHP
CodeIgniter配置之autoload.php自动加载用法分析
2016/01/20 PHP
jquery实现点击消失的代码
2014/03/03 Javascript
js获取UserControl内容为拼html时提供方便
2014/11/02 Javascript
jQuery常用数据处理方法小结
2015/02/20 Javascript
JavaScript让网页出现渐隐渐显背景颜色的方法
2015/04/21 Javascript
浅谈JavaScript异常处理语句
2015/06/26 Javascript
纯javascript判断查询日期是否为有效日期
2015/08/24 Javascript
JS实现模拟百度搜索“2012世界末日”网页地震撕裂效果代码
2015/10/31 Javascript
Jquery表单验证失败后不提交的解决方法
2016/10/18 Javascript
canvas绘制多边形
2017/02/24 Javascript
JS正则获取HTML元素的方法
2017/03/31 Javascript
判断div滑动到底部的scroll实例代码
2017/11/15 Javascript
Angular中innerHTML标签的样式不起作用的原因解析
2019/06/18 Javascript
改变layer confirm弹窗按钮的颜色方法
2019/09/12 Javascript
nuxt.js添加环境变量,区分项目打包环境操作
2020/11/06 Javascript
python中去空格函数的用法
2014/08/21 Python
python写的一个squid访问日志分析的小程序
2014/09/17 Python
Python中Random和Math模块学习笔记
2015/05/18 Python
python3反转字符串的3种方法(小结)
2019/11/07 Python
opencv设置采集视频分辨率方式
2019/12/10 Python
python GUI库图形界面开发之PyQt5切换按钮控件QPushButton详细使用方法与实例
2020/02/28 Python
解决import tensorflow as tf 出错的原因
2020/04/16 Python
canvas压缩图片以及卡片制作的方法示例
2018/12/04 HTML / CSS
canvas实现烟花的示例代码
2020/01/16 HTML / CSS
AmazeUi Tree(树形结构) 应用小结
2020/08/17 HTML / CSS
Notino罗马尼亚网站:购买香水和化妆品
2019/07/20 全球购物
介绍一下结构化程序设计方法和面向对象程序设计方法的区别
2012/06/27 面试题
高中英语演讲稿范文
2014/04/24 职场文书
师范生求职自荐信
2014/06/14 职场文书
党员干部反四风对照检查材料思想汇报
2014/09/14 职场文书
2014年数学教研组工作总结
2014/12/06 职场文书
写给老婆的保证书
2015/02/27 职场文书
出纳2015年度工作总结范文
2015/10/14 职场文书
高一数学教学反思
2016/02/18 职场文书
Python爬虫网络请求之代理服务器和动态Cookies
2022/04/12 Python