PHP之正则表达式捕获组与非捕获组(详解)


Posted in PHP onJuly 29, 2015

在项目开发过程中正则表示经常会用到,可以说会正则表达式是每个程序员最基本的要求,初学者在刚接触正则表达式都感到很吃力。最近看到一位朋友的博客写的《PHP正则表达式》获益颇多,在章节对通配符以及捕获数据非常感兴趣。这两章节刚好也涉及到了正则表达式的捕获组和非捕获组的内容,以此来分析这方面的内容

我们知道,在正则表达式下(x) 表示匹配'x'并记录匹配的值。这只是比较通俗的说法,甚至说这是不严谨的说法,只有()捕获组形式才会记录匹配的值。非捕获组则只匹配,不记录。

捕获组:

(pattern)

这种形式是我们见到最多的一种形式,匹配并返回捕获结果,可以嵌套,组号顺序从左到右依次排列‘。

$regex = '/(ab(c)+)+d(e)?/';    

$str = 'abccde';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => abccde [1] => abcc [2] => c [3] => e )
(?P<name>pattern)

这种方式虽然看起来在构造正则表达式的时候略微复杂一点,但实质上与(pattern)一样。最大的优势体现在对结果处理上,程序员可以直接根据自己设置的<name>直接快速调用结果,而不用再去数需要的结果在第几个子组了。

$regex = '/(?P<group1>\w(?P<group2>\w))abc(?P<group3>\w)45/';
$str = 'fsabcd45';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}
 

匹配结果:

Array ( [0] => fsabcd45 [group1] => fs [1] => fs [group2] => s [2] => s [group3] => d [3] => d )
\num

num是一个整数,是对捕获组的反向引用。  例如\2表示第二个子组匹配值,\表示第一个子组匹配值

$regex = '/(\w)(\w)\2\1/';    

$str = 'abba';

$matches = array();

 

if(preg_match($regex, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => abba [1] => a [2] => b )

注意,这里我疏忽了一个小细节,一开始我第一样代码是 $regex = “/(\w)(\w)\2\1/”;  结果返回无匹配结果,经过调试后,发现这里只能用' '。'与" 用法差别大家还是需要注意下。

  \k< name >

了解了(?P<name>pattern)与\num,这个就不难理解了。\k< name >是对命名捕获组的反向引用。其中 name 是捕获组名。

$regex='/(?P<name>\w)abc\k<name>/';
$str="fabcf";

echo preg_match_all($regex, $str,$matches);

print_r($matches);

匹配结果:

Array ( [0] => Array ( [0] => fabcf ) [name] => Array ( [0] => f ) [1] => Array ( [0] => f ) )

非捕获组:

(?:pattern)

与(pattern)的唯一区别是,匹配pattern但不捕获匹配结果。这里便不再举例。

还有四种方式实际上讲的是一个事情:预查。

预查分为正向预查与反向预查。根据字面理解,正向预查是判断匹配字符串后面某些字符存在与否,而反向预查则是判断匹配字符串前面某些字符存在与否。

正向预查判断存在使用(?=pattern),判断不存在使用(?!pattern)。

反向预查判断存在使用(?<=pattern),判断不存在使用(?<!pattern)。

$regx='/(?<=a)bc(?=d)/';
$str="abcd ebcd abce ebca";

if(preg_match_all($regx, $str, $matches)){

    print_r($matches);

}

匹配结果:

Array ( [0] => Array ( [0] => bc) )

这四种形式使用的是否只要注意好相对匹配字符串的位置和断言肯定还是否定,就会很快掌握。

另外,预查的四种形式是零宽度的,匹配的时候只做一个判断,本身是不占位置的。/HE(?=L)LLO/ 与HELLO匹配,而/HE(?=L)LO/与HELLO是不匹配的。毕竟但从字节数上两者就是不匹配的,前者只有4个,而后者有5个。

以上就是PHP之正则表达式捕获组与非捕获组详解的全部内容,希望对大家有所启迪。

PHP 相关文章推荐
提升PHP执行速度全攻略(上)
Oct 09 PHP
Search Engine Friendly的URL设计
Oct 09 PHP
图形数字验证代码
Oct 09 PHP
PHP函数preg_match_all正则表达式的基本使用详细解析
Aug 31 PHP
php定义数组和使用示例(php数组的定义方法)
Mar 29 PHP
PHP整数取余返回负数的相关解决方法
May 15 PHP
PHP中使用json数据格式定义字面量对象的方法
Aug 20 PHP
php单文件版在线代码编辑器
Mar 12 PHP
PHP赋值的内部是如何跑的详解
Jan 13 PHP
php 多继承的几种常见实现方法示例
Nov 18 PHP
PHP实现简单日历类编写
Aug 28 PHP
解决thinkphp6(tp6)在状态码500下不报错,或者显示错误“Malformed UTF-8 characters”的问题
Apr 01 PHP
PHP实现的简单缓存类
Jul 29 #PHP
PHP实现简单爬虫的方法
Jul 29 #PHP
php获取网站百度快照日期的方法
Jul 29 #PHP
如何通过Linux命令行使用和运行PHP脚本
Jul 29 #PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 #PHP
PHP模拟QQ登录的方法
Jul 29 #PHP
PHP实现动态web服务器方法
Jul 29 #PHP
You might like
php操作xml
2013/10/27 PHP
Laravel重写用户登录简单示例
2016/10/08 PHP
一些不错的js函数ajax
2008/08/20 Javascript
JavaScript 字符编码规则
2009/05/04 Javascript
document.getElementById介绍
2011/09/13 Javascript
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
通过JS动态创建一个html DOM元素并显示
2014/10/15 Javascript
基于jQuery的select下拉框选择触发事件实例分析
2016/11/18 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
使用jQuery和ajax代替iframe的方法(详解)
2017/04/12 jQuery
微信小程序 开发之全局配置
2017/05/05 Javascript
javaScript之split与join的区别(详解)
2017/11/08 Javascript
node.js自动上传ftp的脚本分享
2018/06/16 Javascript
30分钟精通React今年最劲爆的新特性——React Hooks
2019/03/11 Javascript
Python编写百度贴吧的简单爬虫
2015/04/02 Python
详解Python中的__new__()方法的使用
2015/04/09 Python
python 多线程实现检测服务器在线情况
2015/11/25 Python
Python的网络编程库Gevent的安装及使用技巧
2016/06/24 Python
Python遍历某目录下的所有文件夹与文件路径
2018/03/15 Python
python numpy 部分排序 寻找最大的前几个数的方法
2018/06/27 Python
使用pandas实现csv/excel sheet互相转换的方法
2018/12/10 Python
快速排序的四种python实现(推荐)
2019/04/03 Python
解决Django后台ManyToManyField显示成Object的问题
2019/08/09 Python
Python3 requests文件下载 期间显示文件信息和下载进度代码实例
2019/08/16 Python
django实现支付宝支付实例讲解
2019/10/17 Python
基于Django统计博客文章阅读量
2019/10/29 Python
阿根廷网上配眼镜:SmartBuyGlasses阿根廷
2016/08/19 全球购物
英国在线药房:Express Chemist
2019/03/28 全球购物
Sony C++笔试题
2013/03/10 面试题
英语复习计划
2015/01/19 职场文书
2015年度党员自我评价范文
2015/03/03 职场文书
同乡会致辞
2015/07/30 职场文书
学会感恩主题班会
2015/08/12 职场文书
《水浒传》读后感3篇(范文)
2019/09/19 职场文书
CentOS安装Nginx并部署vue
2022/04/12 Servers
Spring boot实现上传文件到本地服务器
2022/08/14 Java/Android