分组

分组在正则中用()表示,根据小菜理解,分组的作用有两个:

1.将某些规律看成是一组,然后进行组级别的重复,可以得到意想不到的效果。

2.分组之后,可以通过后向引用简化表达式(\1 或者$1)。

分组举列

先来看第一个作用,对于IP地址的匹配,简单的可以写为如下形式:

 \d{,}.\d{,}.\d{,}.\d{,}

但仔细观察,我们可以发现一定的规律,可以把.\d{1,3}看成一个整体,也就是把他们看成一组,再把这个组重复3次即可。表达式如下:

 \d{,}(.\d{,}){}

再来看第二个作用,就拿匹配<title>xxx</title>标签来说,简单的正则可以这样写:

<title>.*</title>

可以看出,上边表达式中有两个title,完全一样,其实可以通过分组简写。表达式如下:

<(title)>.*</\>

对于分组而言,整个表达式永远算作第0组,在本例中,第0组是<(title)>.*</\1>,然后从左到右,依次为分组编号,因此,(title)是第1组。

注意:

用\1这种语法,可以引用某组的文本内容,但不能引用正则表达式。

例如刚刚的IP地址正则表达式为\d{1,3}(.\d{1,3}){3},里边的\d{1,3}重复了两次,如果利用后向引用简化,表达式如下:

 (\d{,})(.\){}

经过实际测试,会发现这样写是错误的,为什么呢?

后向引用,引用的仅仅是文本内容,而不是正则表达式!

也就是说,组中的内容一旦匹配成功,后向引用,引用的就是匹配成功后的内容,引用的是结果,而不是表达式。

因此,(\d{1,3})(.\1){3}这个表达式实际上匹配的是四个数都相同的IP地址,比如:123.123.123.123。

不捕获

不捕获就是在分组的前边加上?:,可以在不需要捕获分组的表达式中使用,加快表达式执行速度。

就拿匹配<title>xxx</title>标签来说,通过分组可以简写为

<(title)>.*</\> 

但是如果是(?:title),则\1就不能捕获到这个子组了,只能捕获第一个出现的非?:的分组作为\1

同时注意(?:title)本身会在完整匹配中,只是不在子组中,注意和断言的区别

$str="ab123ff";
//正常,完整匹配为ab123ff, 有两个子组ab, ff
preg_match_all("|([a-z]{2}).*([a-z]{2})|U", $str, $out);echo "<pre>";
print_r($out);
echo "</pre>"; //不捕获分组,完整匹配为ab23ff, 有一个子组ff
preg_match_all("|(?:[a-z]{2}).*([a-z]{2})|U", $str, $out);echo "<pre>";
print_r($out);
echo "</pre>"; //断言,完整匹配为123ff, 有一个子组ff
preg_match_all("|(?<=[a-z]{2}).*([a-z]{2})|U", $str, $out);echo "<pre>";
print_r($out);
echo "</pre>";

断言

所谓断言,就是指明某个字符串前边或者后边,将会出现满足某种规律的字符串。

就拿匹配<title>xxx</title>标签来说,我们想要的是xxx,它没有规律,但是它前边肯定会有<title>,后边肯定会有</title>,这就足够了。

想指定xxx前肯定会出现<title>,就用正后发断言,表达式:(?<=<title>).*

想指定xxx后边肯定会出现</title>,就用正先行断言,表达式:.*(?=</title>)

两个加在一起,就是(?<=<title>).*(?=</title>)

这样就能匹配到xxx,匹配的内容不包括断言的内容,即完整的匹配就是xxx,不会包含<title>和</title>,子组中也不包含。

对正后发和正先行的解释:

其实掌握了规律,就很简单了,无论是先行还是后发,都是相对于xxx而言的,也就是相对于目标字符串而言。

假如目标字符串后边有条件,可以理解为目标字符串在前,就用先行断言,放在目标字符串之后。

假如目标字符串前边有条件,可以理解为目标字符串在后,就用后发断言,放在目标字符串之前。

假如指定满足某个条件,就是正。

假如指定不满足某个条件,就是负。

断言只是条件,帮你找到真正需要的字符串,本身并不会匹配!

!表示正好相反的意思,就是把=换成了!,看表格解释,X代表字符

(?=X )
零宽度正先行断言。仅当子表达式 X 在 此位置的右侧匹配时才继续匹配。例如,\w+(?=\d) 与后跟数字的单词匹配,而不与该数字匹配。此构造不会回溯。
(?!X)
零宽度负先行断言。仅当子表达式 X 不在 此位置的右侧匹配时才继续匹配。例如,例如,\w+(?!\d) 与后不跟数字的单词匹配,而不与该数字匹配 。
(?<=X)
零宽度正后发断言。仅当子表达式 X 在 此位置的左侧匹配时才继续匹配。例如,(?<=19)99 与跟在 19 后面的 99 的实例匹配。此构造不会回溯。
(?<!X)
零宽度负后发断言。仅当子表达式 X 不在此位置的左侧匹配时才继续匹配。例如,(?<!19)99 与不跟在 19 后面的 99 的实例匹配
 
 

正则表达式分组()、不捕获(?:)和断言(?<=)详解的更多相关文章

  1. python 之re模块(正则表达式) 分组、断言详解

    正则表达式分组.断言详解   提示:阅读本文需要有一定的正则表达式基础. 正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下. 如果 ...

  2. jmeter --响应断言详解

    jmeter --响应断言详解 响应断言 :对服务器的响应进行断言校验 (1)应用范围: main sample and sub sample, main sample only , sub-samp ...

  3. Mysql高手系列 - 第20篇:异常捕获及处理详解(实战经验)

    Mysql系列的目标是:通过这个系列从入门到全面掌握一个高级开发所需要的全部技能. 这是Mysql系列第20篇. 环境:mysql5.7.25,cmd命令中进行演示. 代码中被[]包含的表示可选,|符 ...

  4. Jmeter接口之响应断言详解

    响应断言 : 对服务器的响应进行断言校验 Apply to 应用范围: main sample and sub sample, main sample only , sub-sample only , ...

  5. junit 常用注解 + junit 断言详解

    @Test: 在junit3中,是通过对测试类和测试方法的命名来确定是否是测试,且所有的测试类必须继承junit的测试基类.在junit4中,定义一个测试方法变得简单很多,只需要在方法前加上@Test ...

  6. 『动善时』JMeter基础 — 29、JMeter响应断言详解

    目录 1.JMeter断言介绍 2.响应断言组件界面详解 3.响应断言组件的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 (3)响应断言界面内容 (4)查看运行结果 (5)断言结果组件 ...

  7. 『动善时』JMeter基础 — 30、JMeter中JSON断言详解

    目录 1.JSON断言组件界面详解 2.JSON断言组件的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 (3)JSON断言界面内容 (4)查看运行结果 (5)断言结果组件说明 3.JS ...

  8. 『动善时』JMeter基础 — 31、JMeter中BeanShell断言详解

    目录 1.BeanShell简介 2.Beanshell的内置变量和方法 3.BeanShell断言界面详解 4.BeanShell断言的使用 (1)测试计划内包含的元件 (2)登陆接口请求界面内容 ...

  9. 正则表达式零宽断言详解(?=,?<=,?!,?<!)

    在使用正则表达式时,有时我们需要捕获的内容前后必须是特定内容,但又不捕获这些特定内容的时候,零宽断言就起到作用了 正则表达式零宽断言: 零宽断言是正则表达式中的难点,所以重点从匹配原理方面进行分析.零 ...

随机推荐

  1. 简单的JS控制button颜色随点击更改

    先上效果图: 默认“今日”是选中状态,是行内样式: <button type="button" id="today" class="btn-li ...

  2. HTML5文件系统API和资料整理

    来着火狐开发网络的官方文档:点我打开 : W3C的官方文档: 点我打开 : 园友的博客:  点我打开: 浏览器兼容性, 好了就chrome支持, 我刚刚更新的火狐37也不支持, nice, 太nice ...

  3. nodeJS+express+Jade写一个局域网聊天应用(node基础)

    为了复习一下nodeJS, 而且socketIO这东西听起来就好高端有木有, 而且有人写过了open, 也可以作为自己的参考有木有, 点击下载源代码: express是4.x的版本, 跟以前的配置有些 ...

  4. 17B

    贪心,之前先bfs判断是否联通,然后,反向建图,找一个未选择的点,找与他距离最近的点连边,因为每个点都要被选择,所以一个点离他最近的另一个点肯定也被选择,可以贪心 #include<queue& ...

  5. Mysql-windows下修改密码

    忘记密码修改(以下各种方法视情况而使用,本人测试,有些都是案情况才可行,但都是有设置成功过) 注:修改密码成功后一定要记得刷新下权限(否则将导致不能使用当前用户连接) mysql>FLUSH P ...

  6. [转]关于网络通信,byte[]和String的转换问题

    最近的项目中要使用到把byte[]类型转换成String字符串然后通过网络发送,但发现发现出去的字符串和获取的字符串虽然是一样的,但当用String的getBytes()的方法得到的byte[]跟原来 ...

  7. plsql dev引起的数据库被黑勒索比特币实现原理分析和解决方案

    转自http://www.xifenfei.com/2016/11/plsql-dev-hacker-bitcoin.html afterconnect.sql是plsql dev登录后自动执行脚本, ...

  8. 华硕笔记本之secure boot

    在ubuntu下安装cuda的时候,一直装不好,cuda-7.5.run已经装好了,但是编译cuda的例程时失败,提示cuda的库链接不上. 初步判断是secure boot的问题,因为在开启X的情况 ...

  9. android逆向学习小结--CrackMe_1

    断断续续的总算的把android开发和逆向的这两本书看完了,虽然没有java,和android开发的基础,但总体感觉起来还是比较能接收的,毕竟都是触类旁通的.当然要深入的话还需要对这门语言的细节特性和 ...

  10. 正则表达式——语法

    正则表达式(regular expression)--描述一种字符串匹配模式,可以用来检测一个字符串是否包含特定的子串.用其他字符串将其代替.提取出某个符合要求的子串. 正则表达式   由普通字符 和 ...