浅谈PHP正则中的捕获组与非捕获组

今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到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。

如果有多个括号或嵌套括号,按左边括号出现的顺序来进行编号,如图:

按图中的匹配模式匹配时,捕获组的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正则中的捕获组与非捕获组就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

时间: 2024-10-23 15:37:30

浅谈PHP正则中的捕获组与非捕获组的相关文章

浅谈PHP正则中的捕获组与非捕获组_php实例

今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可行的,于是总结一下,分享的同时也希望有大神和细心的学习者找到我理解中出现的问题. 什么是捕获组 我们先看一下PHP的正则匹配函数 int preg_match ( string $pattern , string $subject [, array &$matches [, int $flags =

用户体验设计:浅谈可用性测试中沟通的技巧

文章描述:如何快速解除用户防备?--浅谈可用性测试中沟通的技巧.   一般来说,在产品的设计和开发过程中,不同阶段会使用到不同的用户研究方法.比如,在产品正式发布之前,通常会进行可用性测试.可用性测试,是指让一群有代表性的用户尝试对产品进行典型操作,同时观察员和开发人员在一旁观察.聆听.记录.该产品可能是一个网站.软件,或其他任何产品,它可能已经做好,也可能尚未成型. 对于一个典型的可用行测试,我们可以:1. 通过观察用户在使用产品过程中出现的一些问题,发现产品的可用性问题2. 从测试参与者的表

浅谈网站SEO中避免pr高权重外链建设误区

做网站优化的站长需要经常要去发外链或者是交换友情链接,网站外链的数量和质量对网站的关键词排名有着非常重要的影响.我们去和别的网站交换友情链接,首先要考虑的就是对方网站是否和我们的网站门当户对.大家都喜欢高pr和高权重,认为权重高的网站自然能传递给我们网站不错的权重,从而提高我们网站的关键词排名.但事实上高pr和高权重并不一定会给我们网站带来好处,有时候还会影响搜索引擎对我们网站的印象. 网站优化中做外链最主要的就是把其他页面的权重传递给我们的网站,提高我们网站自身的权重,从而使关键词在搜索引擎中

浅谈SQL Server中的快照

原文:浅谈SQL Server中的快照 简介     数据库快照,正如其名称所示那样,是数据库在某一时间点的视图.是SQL Server在2005之后的版本引入的特性.快照的应用场景比较多,但快照设计最开始的目的是为了报表服务.比如我需要出2011的资产负债表,这需要数据保持在2011年12月31日零点时的状态,则利用快照可以实现这一点.快照还可以和镜像结合来达到读写分离的目的.下面我们来看什么是快照.   什么是快照     数据库快照是 SQL Server 数据库(源数据库)的只读静态视图

浅谈云计算发展中亟待解决的问题

发展云计算不能"跟风攀比""乱云飞渡"--浅谈云计算发展中亟待解决好的几个问题 到目前为止,中国已经掀起了一场云计算发展的热潮.从媒体的热炒,到资本的造势,再到大量学术活动裹挟着的商务宣传,已经拼命地为云计算概念加温.加上Google.IBM.微软等IT巨头们以前所未有的速度和规模进行云计算的推广和炒作,更是把云计算推上了峰巅.云规划,云纲要,云项目.云基地似乎已经成为各级政府新的发展规划中一道最亮丽的风景线. 随着各地云计算热情的空前高涨,一时间多地政府纷纷出台优

浅谈spring容器中bean的初始化_java

当我们在spring容器中添加一个bean时,如果没有指明它的scope属性,则默认是singleton,也就是单例的. 例如先声明一个bean: public class People { private String name; private String sex; public String getName() { return name; } public void setName(String name) { this.name = name; } public String get

浅谈MySQL存储过程中declare和set定义变量的区别_Mysql

在存储过程中常看到declare定义的变量和@set定义的变量.简单的来说,declare定义的类似是局部变量,@set定义的类似全局变量. 1.declare定义的变量类似java类中的局部变量,仅在类中生效.即只在存储过程中的begin和end之间生效. 2.@set定义的变量,叫做会话变量,也叫用户定义变量,在整个会话中都起作用(比如某个应用的一个连接过程中),即这个变量可以在被调用的存储过程或者代码之间共享数据.如何理解呢?可以看下面这个简单例子,很好理解.  (1)先执行下面脚本,创建

浅谈 js 正则字面量 与 new RegExp 执行效率

原文:浅谈 js 正则字面量 与 new RegExp 执行效率 前几天谈了正则匹配 js 字符串的问题:<js 正则学习小记之匹配字符串> 和 <js 正则学习小记之匹配字符串优化篇>.里面讲到了优化正则起到提升性能的问题,但是能提升多少呢?于是我去测试了,发现TMD几乎微乎其微,我用1千字符串进行100万次匹配测试,优不优化根本没区别. 这不科学,我白看了这么多天正则,上天这是在玩弄我么. 突然我想到了 compile 方法,然后去测试了下,奇迹出现了,果然优化过的快了不少.

浅谈js函数中的实例对象、类对象、局部变量(局部函数)_javascript技巧

定义 function Person(national,age) { this.age = age; //实例对象,每个示例不同 Person.national = national; //类对象,所用实例公用 var bb = 0; //局部变量,外面不能访问(类似局部函数) } 调用 var p = new Person("中国", 29); document.writeln("age:" + p.age); document.writeln("obj