熟练掌握正则表达式是每个程序员的基础要求,对于每个初学者来说会被正则表达式一连串字符弄得头晕眼花。博主便会如此,一直对正则表达式有种莫名的恐惧。近来看到另一位博友写的 《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 正则表达式捕获组与非捕获组的更多相关文章

  1. JAVA正则表达式-捕获组与非捕获组

    Java捕获组与非捕获组的问题 先看例子: import java.util.regex.Matcher; import java.util.regex.Pattern; public class P ...

  2. JavaScript正则表达式模式匹配(4)——使用exec返回数组、捕获性分组和非捕获性分组、嵌套分组

    使用exec返回数组 var pattern=/^[a-z]+\s[0-9]{4}$/; var str='google 2012'; alert(pattern.exec(str)); //返回一个 ...

  3. split与re.split/捕获分组和非捕获分组/startswith和endswith和fnmatch/finditer 笔记

    split()对字符串进行划分: >>> a = 'a b c d' >>> a.split(' ') ['a', 'b', 'c', 'd'] 复杂一些可以使用r ...

  4. PHP正则中的捕获组与非捕获组

    今天遇到一个正则匹配的问题,忽然翻到有捕获组的概念,手册上也是一略而过,百度时无意翻到C#和Java中有对正则捕获组的特殊用法,搜索关键词有PHP时竟然没有相关内容,自己试了一下,发现在PHP中也是可 ...

  5. java 捕获组与非捕获组

    非捕获组:格式:(?:xxxx), 如:(?:aaa)\\w+(bbb)\\1,\\1 代表重复捕获的第一组即是(bbb) public static void main(String[] args) ...

  6. js 正则表达式,分组,非捕获或 环视的使用

    定位一个字符串中,匹配与定位重复字符中的最后一个字符: 例子: <script type="text/javascript"> var str="http:/ ...

  7. Python中正则匹配使用findall,捕获分组(xxx)和非捕获分组(?:xxx)的差异

    转自:https://blog.csdn.net/qq_42739440/article/details/81117919 下面是我在用findall匹配字符串时遇到的一个坑,分享出来供大家跳坑. 例 ...

  8. java正则表达式 非捕获组详解

    这几天看了下正则表达式,对非捕获组(non-capturing)进行下总结.主要总结 1个 + 2组  一共5个.(?:X) (?=X) (?<=X) (?!X) (?<!X) 一.先从( ...

  9. JavaScript正则表达式-非捕获性分组

    非捕获性分组定义子表达式可以作为整体被修饰但是子表达式匹配结果不会被存储. 非捕获性分组通过将子表达式放在"?:"符号后. str = "img1.jpg,img2.jp ...

随机推荐

  1. Angularjs的My97DatePicker扩展

    对于日期控件来说,My97DatePicker算得上是个优秀的东东了.好几个项目都用的它. 新项目中也是一样,不过区别是使用的Angularjs.二者不会冲突,不过以往情况下使用的 ng-model ...

  2. java使用this关键字调用本类重载构造器

    在构造器中可以调用本类的其他重载构造器,不能使用构造器名称来调用另一个构造器,而是应该使用Java特定的this(-.)来调用. this(-.)方法必须出现在构造器中的第一行,用来调用其他重载构造器 ...

  3. 关于Math类的round、floor、ceil三个方法

    一.Math类这三个方法的简介 1.round():取最接近的值. 对于这个方法,查看源代码,其实现如下: public static long round(double a) { if (a != ...

  4. IE6/7/8不支持jQuery创建非闭合格式的链接A

    代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <scri ...

  5. VirtualBox: Effective UID is not root (euid=1000 egid=100 uid=1000 gid=100)

    桌面上运行virtualbox出错: The virtual machine 'xp' has terminated unexpectedly during startup with exit cod ...

  6. css常见问题

    CSS: 1.垂直居中布局 (1)已知宽高 (2)未知宽高 https://segmentfault.com/q/1010000004073623 2.文字退格 text-indent: 4em; 3 ...

  7. linux文件压缩与打包

    在linux中常见的压缩命令 首先,在linux中压缩文件的扩展名大多是 *.gz gzip程序压缩的文件 *.bz2 bzip2程序压缩的文件 *.tar tar程序打包的数据,并没有压缩过 *.t ...

  8. 备忘:文本编辑器(z.B. Sublime Text 2)策略,git策略

    1.以Sublime Text 2 为例: 新建一个test.py文件,敲完例程 代码 之后,再另存为比如 if.py, list_tuple.py云云 而test.py可以一直用来编辑 2.git ...

  9. Quicksum -SilverN

    quicksum Given a string of digits, find the minimum number of additions required for the string to e ...

  10. js开发工具箱

    昨天看到一位大牛的博客,里面有一篇文章“web前端开发分享-目录”,文章中提到的一个给前端er用的一个js开发工具箱.自己使用了一下,非常好用,代码压缩,代码美化,加密,解密之类基本功能都有,生成二维 ...