正则表达式断言、巡视(Assertions)、正向断言、反向断言介绍

断言(Assertions)在正则表达式概念里面难理解,它通常指的是在目标字符串的当前匹配位置进行的一种测试但这种测试并不占用目标字符串,也即不会移动模式在目标字符串中的当前匹配位置。详细可以看看,正则表达式匹配解析过程探讨分析(正则表达式匹配原理),里面提到“零宽度“很多元字符,只是对特殊位置进行匹配,它们可以理解为断言。

断言元字符

常见断言元字符有: \b, \B, \A, \Z, \z, ^ ,$ 它们只是表示特殊位置,各自作用如有字符串AB,带位置表示为:0A1B2

元字符 意义(以上面带位置字符串说明)
^ 行首,字符串首 表示位置0
$ 行尾,字符串尾部,表示位置2
\b 字分界线,可以表示:0,2位置
\B 非字分界线,可以表示1位置
\A 目标的开头(独立于多行模式) 表示位置0
\Z 目标的结尾或位于结尾的换行符前(独立于多行模式) 表示位置2
\z 目标的结尾(独立于多行模式)表示位置2
\G 目标中的第一个匹配位置
A,Z,z,G很少使用

这些断言的测试都是一些基于当前位置的测试,断言还支持更多复杂的测试条件。更复杂的断言以子模式方式来表示,它包括先行(前向)断言(Lookahead assertions)和后行(后向)断言(Lookbehind assertions),这些断言判断只做匹配判断条件,不会记录在匹配结果中,不会匹配字符。

先行断言、正向断言、正向巡视(Lookahead assertions)

先行断言,常有表示(?=pattern),从当前匹配位置开始测试后面匹配字符串是否成立,还有(?!pattern)这样两种格式,我们来看看一个例子。源字符串:“abc100”,正则表达式是:
/[a-z]+(?=\d+)/ ,我们分析下过程如下图:

首先由正则表达式字符 [a-z]+ 取得控制权,匹配字符:”abc”,位置从”0”开始匹配,变成3。从该位置测试/d+是否成立。匹配到字符100,返回成立。因此正则表达式正向断言成功。返回匹配字符串”abc”

(?!pattern) 只是,正向匹配,当后面没有匹配成功,将返回真。以下是系统源字符串:abc100,测试结果如下:

后行断言、反向断言、反向巡视(Lookbehind assertions)

后行断言,常见表达式是:(?<=pattern)或者(?<!pattern)格式。正则表达式里面,不要出现不固定长度量词,可能会出现死循环。匹配出错。表示当前位置左边将出现匹配字符,则返回真,后面匹配正常。因为如果它出现在最左边,默认位置从0开始,匹配都是失败的。一般都从后面正则表达式开始匹配,再回溯,直到匹配到为止。我们看看下面例子:源字符串:“abc100+=“,正则表达式是:”(?<=\w)\w+”,匹配过程如下图:

首先由正则表达式字符 /\w+/取得控制权,匹配字符:”abc100”,位置从”0”开始匹配,匹配到6个字符。从该位置0检测左变\w匹配失败。因此/\w+/从字符b开始匹配到”bc100”,测试它左侧有字符”a”,反向断言正确。因此匹配到字符串“bc100”,(?<!pattern),只是没有匹配成功返回真,其它都一样!

后记:从这篇文章,我们发现搜索特点都是从左到有,一般正向断言放到,正则表达式后,反向断言放到匹配正则表达式前。但是,这里也可以放到前或后。这里就不再举例。欢迎交流讨论!

时间: 2015-10-12

javascript 正则表达式分组、断言详解

 javascript 正则表达式分组.断言详解 提示:阅读本文需要有一定的正则表达式基础. 正则表达式中的断言,作为高级应用出现,倒不是因为它有多难,而是概念比较抽象,不容易理解而已,今天就让小菜通俗的讲解一下. 如果不用断言,以往用过的那些表达式,仅仅能获取到有规律的字符串,而不能获取无规律的字符串. 举个例子,比如html源码中有<title>xxx</title>标签,用以前的知识,我们只能确定源码中的<title>和</title>是固定不变的.因

正则基础之 环视 Lookaround

1       环视基础 环视只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果,是零宽度的.环视匹配的最终结果就是一个位置. 环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功. 环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视.顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件. 表达式 说明 (?<=Expression) 逆序肯定环视,表示所在位置左侧能够匹配Exp

正则表达式环视概念与用法分析

本文实例讲述了正则表达式环视概念与用法.分享给大家供大家参考,具体如下: 1.环视又叫预搜索和零宽断言 2.环视又划分为 (?=exp)肯定顺序环视 (?<=exp)肯定逆序环视 (?!exp)否定顺序环视 (?<exp)否定逆序环视 3.环视只占用逻辑位置 不占用物理位置 如:匹配后缀名字为txt的文件 字符:file.txt.file2.exe 正则 \w(?=.exe) 匹配字符串file2 4.环视的用法 (?=exp)肯定顺序环视的2种用法 ① 查找电话号码是132开头的电话 字符:

正则表达式零宽断言详解

正则表达式零宽断言: 零宽断言是正则表达式中的难点,所以本章节重点从匹配原理方面进行一下分析.零宽断言还有其他的名称,例如"环视"或者"预搜索"等等,不过这些都不是我们关注的重点. 一.基本概念: 零宽断言正如它的名字一样,是一种零宽度的匹配,它匹配到的内容不会保存到匹配结果中去,最终匹配结果只是一个位置而已. 作用是给指定位置添加一个限定条件,用来规定此位置之前或者之后的字符必须满足限定条件才能使正则中的字表达式匹配成功. 注意:这里所说的子表达式并非只有用小括号

正则表达式中环视的简单应用示例【基于java】

本文实例讲述了正则表达式中环视的简单应用.分享给大家供大家参考,具体如下: 由于开发工作需要对文本中内容进行过滤,删除或替换掉一些无用的或不符合要求的信息.于是发现一个问题,某一类工程性文本中,用到很多英文写法相同.但含义不同的单位,需要将其分别转为真实含义对应的汉字.比如:"粘度为17s,移动距离为350厘米,要求混凝土必须内实外光.振捣时间为30s.",很明显第一个s是粘度的单位,第二s是时间单位,现在需要将文本中所有表示时间的s替换为"秒",在朋友指引下,发现

正则应用之 逆序环视探索 .

1 问题引出 前几天在CSDN论坛遇到这样一个问题. 我要通过正则分别取出下面 <font color="#008000"> 与 </font> 之间的字符串 1.在 <font color="#008000"> 与 </font> 之间的字符串是没法固定的,是随机自动生成的 2.其中 <font color="#008000"> 与 </font>的数量也是没法固定的,也是

正则表达式之零宽断言实例详解【基于PHP】

本文实例讲述了正则表达式之零宽断言.分享给大家供大家参考,具体如下: 前言 之前我曾写了一篇关于正则表达式的文章(http://www.jb51.net/article/111359.htm) 在该文章中详细介绍了正则,但是关于零宽断言介绍却是很少提及到.现在将该内容补充一下.在本文中,主要解决如下问题: ① 什么是零宽断言,为什么要使用零宽断言 ② 怎样使用零宽断言 概念 零宽断言,大多地方这样定义它,用于查找在某些内容(但并不包括这些内容)之前或之后的东西,也就是说它们像 \b ^ $ \<

正则匹配原理之 逆序环视深入 .

说明:部分内容有待进一步研究和修正,因为最近工作太忙,暂时抽不出时间来,未研究过的可以跳过这一篇,想研究的不要被我的思路所左右了,有研究清楚的还请指正1 问题引出 前几天在CSDN论坛遇到这样一个问题: var str="8912341253789"; 需要将这个字符串中的重复的数字给去掉,也就是结果89123457. 首先需要说明的是,这种需求并不适合用正则来实现,至少,正则不是最好的实现方式. 这个问题本身不是本文讨论的重点,本文所要讨论的,主要是由这一问题的解决方案而引出的另一个

正则基础之 NFA引擎匹配原理

1       为什么要了解引擎匹配原理 一个个音符杂乱无章的组合在一起,弹奏出的或许就是噪音,同样的音符经过作曲家的手,就可以谱出非常动听的乐曲,一个演奏者同样可以照着乐谱奏出动听的乐曲,但他/她或许不知道该如何去改变音符的组合,使得乐曲更动听. 作为正则的使用者也一样,不懂正则引擎原理的情况下,同样可以写出满足需求的正则,但是不知道原理,却很难写出高效且没有隐患的正则.所以对于经常使用正则,或是有兴趣深入学习正则的人,还是有必要了解一下正则引擎的匹配原理的. 2       正则表达式引擎

JS逆序遍历实现代码

最常用的遍历方式为for语句(也有递归.while方式).当我们遍历一个数组的时候,我们一般会这么做: 复制代码 代码如下: var arr = [1,2,3,4,5,6,7,8,9,10]; for(var i=0,total=arr.length;i<total;i++){   console.log(i,arr[i]); } 这就是最常用的遍历方式:正序遍历.它从数组的第一项依次走到最后一项. 那为什么今天小剧还会提到逆序遍历呢? 这里不得不提下小剧写的组件里最常用的一个模块:events

C语言解字符串逆序和单向链表逆序问题的代码示例

字符串逆序 上次面试碰到一个单向链表逆序的题目,幸好对字符串逆序比较熟悉,类比做出来了.字符串逆序比较简单,直接上代码: void stringReverse(char* p1,char* p2) { if(p1==p2)return; //swap the value of p1 ,p2 *p1=(*p1)+(*p2); *p2=(*p1)-(*p2); *p1=(*p1)-(*p2); if(p1==p2-1)return; else stringReverse(++p1,--p2); }

面试题:用 Java 逆序打印链表

昨天的 Java 实现单例模式 中,我们的双重检验锁机制因为指令重排序问题而引入了 volatile 关键字,不少朋友问我,到底为啥要加 volatile 这个关键字呀,而它,到底又有什么神奇的作用呢? 对 volatile 这个关键字,在昨天的讲解中我们简单说了一下:被 volatile 修饰的共享变量,都会具有下面两个属性: 保证不同线程对该变量操作的内存可见性. 禁止指令重排序. 共享变量:如果一个变量在多个线程的工作内存中都存在副本,那么这个变量就是这几个线程的共享变量. 可见性:一个线

MongoDB查询之高级操作详解(多条件查询、正则匹配查询等)

MongoDB查询之高级操作 语法介绍 MongoDB查询文档使用find()方法,同时find()方法以非结构化的方式来显示所有查询到的文档. -- 1.基本语法 db.collection.find(query, projection) -- 返回所有符合查询条件的文档 db.collection.findOne(query, projection) -- 返回第一个符合查询条件的文档 -- query:可选,查询条件操作符,用于指定查询条件 -- projection:可选,投影操作符,用

PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】

本文实例总结了PHP字符串逆序排列实现方法.分享给大家供大家参考,具体如下: 关于字符串的逆序排列,最简单的使用PHP函数strrev()的测试代码如下: header('Content-type: text/html; charset=utf-8'); $str = implode('', range(9, 0)); print '< p><strong>Before reversed: </strong>'.$str.'< /p>'; print '&l

php与javascript正则匹配中文的方法分析

本文实例讲述了php与javascript正则匹配中文的方法.分享给大家供大家参考,具体如下: php中正则匹配utf-8中文: (重点是:[\x{4e00}-\x{9fa5}]+) $str = "我们"; if (preg_match("/^[\x{4e00}-\x{9fa5}]+$/u",$str,$arr)) { print("该字符串全部是中文"); echo '<pre>'; print_r($arr); } else {

编程语言中十六进制的正则匹配

它由0-9,A-F,组成.与10进制的对应关系是:0-9对应0-9;A-F对应10-15;N进制的数可以用0---(N-1)的数表示超过9的用字母A-F. 也就是由字符:012345679ABCDEF 组成 C语言中的16进制数必须以 0x开头.比如 0x1表示一个16进制数.而1则表示一个十进制.另外如:0xff,0xFF,0X102A,等等.其中的x也不区分大小写.(注意:0x中的0是数字0,而不是字母O) 所以C或C++等编程语言的正则匹配为: 复制代码 代码如下: \b0[xX][0-9