找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 606|回复: 0
打印 上一主题 下一主题

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

[复制链接]

2560

主题

2560

帖子

7622

积分

论坛元老

Rank: 8Rank: 8

积分
7622
跳转到指定楼层
楼主
发表于 2018-2-14 05:43:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

            在项目开发过程中正则表示经常会用到,可以说会正则表达式是每个程序员最基本的要求,初学者在刚接触正则表达式都感到很吃力。最近看到一位朋友的博客写的《PHP正则表达式》获益颇多,在章节对通配符以及捕获数据非常感兴趣。这两章节刚好也涉及到了正则表达式的捕获组和非捕获组的内容,以此来分析这方面的内容
  我们知道,在正则表达式下(x) 表示匹配'x'并记录匹配的值。这只是比较通俗的说法,甚至说这是不严谨的说法,只有()捕获组形式才会记录匹配的值。非捕获组则只匹配,不记录。
  捕获组:
  (pattern)
这种形式是我们见到最多的一种形式,匹配并返回捕获结果,可以嵌套,组号顺序从左到右依次排列‘。
[U]复制代码[/U] 代码如下:
$regex = '/(ab(c)+)+d(e)?/';   
$str = 'abccde';
$matches = array();

if(preg_match($regex, $str, $matches)){
    print_r($matches);
}
  匹配结果:
[U]复制代码[/U] 代码如下:
Array ( [0] => abccde [1] => abcc [2] => c [3] => e )
  (?Ppattern)
这种方式虽然看起来在构造正则表达式的时候略微复杂一点,但实质上与(pattern)一样。最大的优势体现在对结果处理上,程序员可以直接根据自己设置的直接快速调用结果,而不用再去数需要的结果在第几个子组了。
[U]复制代码[/U] 代码如下:
$regex = '/(?P\w(?P\w))abc(?P\w)45/';
$str = 'fsabcd45';
$matches = array();

if(preg_match($regex, $str, $matches)){
    print_r($matches);
}

  匹配结果:
[U]复制代码[/U] 代码如下:
Array ( [0] => fsabcd45 [group1] => fs [1] => fs [group2] => s [2] => s [group3] => d [3] => d )
  \num
num是一个整数,是对捕获组的反向引用。  例如\2表示第二个子组匹配值,\表示第一个子组匹配值
[U]复制代码[/U] 代码如下:
$regex = '/(\w)(\w)\2\1/';   
$str = 'abba';
$matches = array();

if(preg_match($regex, $str, $matches)){
    print_r($matches);
}
  匹配结果:
[U]复制代码[/U] 代码如下:
Array ( [0] => abba [1] => a [2] => b )
注意,这里我疏忽了一个小细节,一开始我第一样代码是 $regex = “/(\w)(\w)\2\1/”;  结果返回无匹配结果,经过调试后,发现这里只能用' '。'与" 用法差别大家还是需要注意下。
  \k
  了解了(?Ppattern)与\num,这个就不难理解了。\k是对命名捕获组的反向引用。其中 name 是捕获组名。
[U]复制代码[/U] 代码如下:
$regex='/(?P\w)abc\k/';
$str="fabcf";
echo preg_match_all($regex, $str,$matches);
print_r($matches);
  匹配结果:
[U]复制代码[/U] 代码如下:
Array ( [0] => Array ( [0] => fabcf ) [name] => Array ( [0] => f ) [1] => Array ( [0] => f ) )
  非捕获组:
  (?:pattern)
  与(pattern)的唯一区别是,匹配pattern但不捕获匹配结果。这里便不再举例。
  还有四种方式实际上讲的是一个事情:预查。
  预查分为正向预查与反向预查。根据字面理解,正向预查是判断匹配字符串后面某些字符存在与否,而反向预查则是判断匹配字符串前面某些字符存在与否。
  正向预查判断存在使用(?=pattern),判断不存在使用(?!pattern)。
  反向预查判断存在使用(?
[U]复制代码[/U] 代码如下:
$regx='/(?
  匹配结果:
[U]复制代码[/U] 代码如下:
Array ( [0] => Array ( [0] => bc) )
  这四种形式使用的是否只要注意好相对匹配字符串的位置和断言肯定还是否定,就会很快掌握。
  另外,预查的四种形式是零宽度的,匹配的时候只做一个判断,本身是不占位置的。/HE(?=L)LLO/ 与HELLO匹配,而/HE(?=L)LO/与HELLO是不匹配的。毕竟但从字节数上两者就是不匹配的,前者只有4个,而后者有5个。
以上就是PHP之正则表达式捕获组与非捕获组详解的全部内容,希望对大家有所启迪。
            
            
您可能感兴趣的文章:
  • 最常用的PHP正则表达式收集整理
  • PHP 正则表达式常用函数使用小结
  • PHP匹配连续的数字或字母的正则表达式
  • php中字符串和正则表达式详解
  • php过滤HTML标签、属性等正则表达式汇总
  • php使用正则表达式提取字符串中尖括号、小括号、中括号、大括号中的字符串
  • PHP正则表达式的效率 回溯与固化分组
  • PHP正则表达式之捕获组与非捕获组
  • 浅谈PHP正则中的捕获组与非捕获组
  • PHP实现正则表达式分组捕获操作示例
            
  • 分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    用户反馈
    客户端