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

 更新时间:2015年07月29日 16:20:49   作者:DeanChopper  
这篇文章主要介绍了php之正则表达式捕获组与非捕获组的详细介绍,需要的朋友可以参考下

在项目开发过程中正则表示经常会用到,可以说会正则表达式是每个程序员最基本的要求,初学者在刚接触正则表达式都感到很吃力。最近看到一位朋友的博客写的《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之正则表达式捕获组与非捕获组详解的全部内容,希望对大家有所启迪。

相关文章

  • phpStorm2020 注册码

    phpStorm2020 注册码

    本文给大家分享phpStorm2020 注册码的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-09-09
  • Zend Framework基于Command命令行建立Zend Framework项目的方法

    Zend Framework基于Command命令行建立Zend Framework项目的方法

    这篇文章主要介绍了Zend Framework基于Command命令行建立Zend Framework项目的方法,较为详细的分析了使用Command命令行建立Zend Framework框架的具体操作步骤与相关注意事项,需要的朋友可以参考下
    2017-02-02
  • PHP 设计模式系列之 specification规格模式

    PHP 设计模式系列之 specification规格模式

    规格模式是组合模式的一种扩展,在框架性开发中使用较多(项目级开发很少使用),通过本文给大家介绍PHP 设计模式系列之 specification规格模式,对specification模式相关知识感兴趣的朋友一起学习吧
    2016-01-01
  • 浅析php适配器模式(Adapter)

    浅析php适配器模式(Adapter)

    本文讲解的是php设计模式的结构性模式的概念以及机构性模式的七种类中的适配器模式,需要的朋友可以参考下
    2014-11-11
  • PHP微信公众号自动发送红包API

    PHP微信公众号自动发送红包API

    微信发红包已经成为当今比较流行的祝福形式,大家都学着使用微信发红包,这篇文章主要为大家详细介绍了PHP微信公众号自动发送红包API,感兴趣的小伙伴们可以参考一下
    2016-06-06
  • PHP创建多级目录的两种方法

    PHP创建多级目录的两种方法

    本文给大家分享两种php创建多级目录的方法,分别是使用递归思想和直接利用mkdir创建。具体创建方法,大家可以参考本教程学习下
    2016-10-10
  • PHP实现自动发送邮件功能代码(qq 邮箱)

    PHP实现自动发送邮件功能代码(qq 邮箱)

    本文给大家分享以qq邮箱为例给大家介绍PHP实现自动发送邮件功能代码,感兴趣的朋友参考下吧
    2017-08-08
  • thinkphp5使用phpmail发送qq邮件的实现过程

    thinkphp5使用phpmail发送qq邮件的实现过程

    这篇文章主要给大家介绍了thinkphp5使用phpmail发送qq邮件的实现过程,文中有详细的代码示例供大家参考,具有一定的参考价值,感兴趣的小伙伴可以自己动手尝试一下
    2023-10-10
  • laravel 5.1下php artisan migrate的使用注意事项总结

    laravel 5.1下php artisan migrate的使用注意事项总结

    这篇文章主要给大家总结介绍了在laravel 5.1下php artisan migrate的使用注意事项,文中介绍的非常详细,对大家使用php artisan migrate具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • Laravel框架创建路由的方法详解

    Laravel框架创建路由的方法详解

    这篇文章主要介绍了Laravel框架创建路由的方法,包括基础路由、多请求路由、路由参数、输出视图等相关原理与使用方法,需要的朋友可以参考下
    2019-09-09

最新评论