前向断言

  • 0 断言
    • 1 前向肯定断言
      • 1.1 语法
      • 1.2 示例
      • 1.3 其他示例
    • 2 前向否定断言
      • 2.1 语法
      • 2.2 示例
      • 2.3 其他示例

0 断言

你将从本文中学到正则表达式里的前向肯定断言前向否定断言,包括它们的语法和示例。

前向断言对于构造一个实用的正则表达式来说非常重要,它是周围断言的其中一(另一种是后向断言)。

断言分两个方向:前和后。所谓前向是指我们书写的方向,从左往右写的话就是右向,与前向相反的方向就是后向。

前向断言,顾名思义,就是看看我们匹配项前面的元素是否满足某条件,满足的话就说明这个匹配项是真的匹配,于是返回这个匹配项,否则就说明这是假匹配,那么就不返回此匹配项。

看到这里,读者也许会思考,这和普通的正则项有啥不同呢?为啥非得另起别名呢?

有不同!且不同有二:

  • 一是普通的正则项在结果中有对应的字符串,参与匹配项的提取,即会被捕获,断言则不被捕获,即不进入最终匹配结果;
  • 二是断言的位置固定,前向断言只用于整个正则式的末尾,后向断言则只用于整个正则式的起始。

看到这里,又有疑问了,断言和泊点 ^$ 的用法不就一样了吗?是的!它们的用法很相似!只是要所用场景稍有不同,^$ 卡匹配串的首尾为字符串的头尾,而断言则卡匹配串的首尾须满足所给条件。

某些参考文献中将 lookahead assertion 翻译为 “正向预查”,正向与前向之辩无谓,但“预查”使用不当。预是预先的意思,预查很容易理解成预先查找,也就是先查找前向表达式,而后进行主匹配项查找。实际上这是不对的, lookahead assertion 不是预先进行的查找的,而是指在找到位于它前面的匹配项之后对接下来的元素进行断言,也就是看看满不满足我们的条件,其中的元素也不是查找的对象,而是用于判断匹配是否成功,并不进入要返回的匹配结果。

1 前向肯定断言

对于这种断言,正则表达式引擎会在找到匹配项后寻找满足断言条件的特定字符或字符串或组(圆括号所包围的项 (...))。若条件满足,则声明此匹配项有效,否则拒绝此匹配项。

1.1 语法

match(?=elem)

其中,match 表示我们想要匹配并返回的字符串的模式; elem 表示前向断言元素,element 的缩写。

若我们找到的与 match 匹配的字符串后紧跟元素 elemt,则匹配才真正成功;否则匹配失败。

前向断言属于组的一种,即由圆括号包裹的一个子表达式,子表达式以问号 ? 起始,等号 = 紧随其后,接着是要查看的元素。

我们定义我们书写顺序的前方,即 xxx 轴正方向为正向;定义我们书写顺序的后方,即 xxx 轴负方向为反向。正向断言就是向前(ahead)看是否满足我们的条件;反向断言就是向后(behind)看是否满足我们的条件。

1.2 示例

现有表达式:a(?=b),它会匹配一个后跟 ba,即能匹配 ababcabz,但不能匹配 babaxca 等。

现在让我们研究下在执行该断言时正则引擎是怎么做的。

测试串:This is a car
正则式:a(?=r)

此正则式将会匹配后紧跟一个 ra

  1. 首先,正则引擎会在字符串里从左向右寻找 a, 于是找到第一个紧跟 isa
  2. 匹配到 a 后,引擎进入组,遇到符号 ?=,于是知道组内是一个前向肯定断言
  3. 接着,引擎看匹配到的 a 的后面是否紧跟元素 r,发现是空格 而非 r,条件不满足,断言失败,引擎接着往前(右)走寻找下一个 a
  4. 引擎找到了紧跟 ca
  5. 匹配到 a 后,引擎再一次进入组,并知道这是一个前向肯定断言;
  6. 接着引擎看匹配到的 a 的后面是否紧跟元素 r,发现是,条件满足,断言成功。
  7. 返回此匹配项 ‘a’。

1.3 其他示例

想匹配:后缀有字符 'a' 的字符串中的 "I love China" 子串,即 "I love Chinaa""I love China" 子串
不想匹配:未后跟字符 'a' 的字符串中的 "I love China" 子串,如 "I love Chinab""I love Chinac" 中的 "I love China" 子串
正则式"I love China(?=a)"

2 前向否定断言

对于这种断言,正则表达式引擎会在找到匹配项后寻找满足断言条件的特定字符或字符串或组(圆括号所包围的项 (...))。若条件满足,则声明此匹配项有效,否则拒绝此匹配项,与上面的肯定断言不同,这里的条件是否定的。

2.1 语法

match(?!elem)

若我们找到的与 match 匹配的字符串后紧跟的元素不是 elemt,则匹配才真正成功;否则匹配失败。

其中,match 表示我们想要匹配并返回的字符串的模式; elem 表示前向断言元素,是元素 element 的缩写,只有当紧跟 match 的元素不是 elem 时才是一个成功的匹配。

a(?!b) 可匹配所有后跟元素不是 ba,如 acadaz,但不会匹配 ababc

2.2 示例

测试串: The number of car sold is larger than car not sold and car being repaired
正则式:car(?!\s+sold)

该正则式会匹配出已售状态(sold)外所有其他状态的车(not sold、being repaired)。

通过前向否定断言,你就可以找到那些没有后跟某些元素的匹配项。

2.3 其他示例

想匹配:为后跟字符 'b' 的字符串中的 "I love China" 子串,如 "I love Chinaa""I love Chinac"
不想匹配:后缀以字符 ' b' 的字符串中的 "I love China" 子串,如 "I love Chinab"
正则式"I love China(?!b)"

前向断言/前向预查/正向断言/正向预查(lookahead assertions)相关推荐

  1. php正则表达式正向预查,javascript正则表达式-----正向预查

    前几篇有用到过, 但是未做深入学习,发现一篇很好的博文 转载自 javascript--正向预查 什么是正向预查?这里有腾讯招聘的一个例子: 如何给一串数字用千分制表示?比如9999999999变成9 ...

  2. 正则表达式: 正向预查和负向预查

    (?:pattern)匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用.这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用.例 ...

  3. 前端运行python代码几种方式_前的解释|前的意思|汉典“前”字的基本解释

    详细字义 ◎ 前 qián 〈动〉 (1) (本义:前进) (2) 同本义 [go forward;go ahead] 前,进也.--<广雅> 然而驱之不前,却之不止.--<韩非子· ...

  4. 入院前、入产房前、分娩前物品准备

    医院待产包及产后囤货包孕期囤货清单 孕期囤货指南 入院前.入产房前.分娩前物品准备温馨提示 一 入院资料 1.女方户口,男方户口的,请携带结婚证: 2.母子保健手册: 3.所有检查单(包括外院检查单) ...

  5. php分前后端吗,前后端分离和不分离的区别是什么

    区别:前后端不分离中,前端页面看到的效果都是由后端控制,由后端渲染页面或重定向,即后端需要控制前端的展示,前端与后端的耦合度很高.前后端分离中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制 ...

  6. 转:说说售前,关于售前,售前软件工程师----写的很好

    说说售前(一):售前的作用 在ITPUB上有个哥们问做售前最需要什么,大多数答:"忽悠".应该说,很有意思的印象词. 浓缩的是精华,细想一下,如果用两个字给售前定性的话,还真找不出 ...

  7. 快慢指针____函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移

    函数将字符串中的字符'*'移到串的前部分,前面的非'*'字符后移,但不能改变非'*'字符的先后顺序,函数返回串中字符'*'的数量.如原始串为:ab**cd**e*12,处理后为*****abcde12 ...

  8. iOS常用于显示几小时前/几天前/几月前/几年前的代码片段

    /*** Retain a formated string with a real date string** @param dateString a real date string, which ...

  9. php时间转分钟前,PHP把时间转换成几分钟前几小时前几天前

    现在很多网站将时间的显示都变得比较人性化,今天项目有一个也需要在对应的资讯后面显示为几分钟前.几小时前,接下来吾爱编程为大家分享一下PHP把时间转换成几分钟前.几小时前几天前的方法,有需要的小伙伴可以 ...

  10. 微信小程序-将时间转换成几秒前 几分钟前 几小时前 几天前等时间格式

    描述: 显示消息时间为 几天前 几小时前 几分钟前:同时一年以上的日期直接显示YYY:MM:DD形式 效果: 方法实现: 可以在utils目录下建一个存放公共方法的文件,将getDateDiff方法放 ...

最新文章

  1. PHP错误日志,解决不显示不记录日志文件等疑难杂症
  2. Nature子刊 | 翟冰等造血干细胞移植中的肠道真菌菌群动态变化与临床结果分析(招聘博后、助研)...
  3. Elasticsearch根据条件进行删除索引命令
  4. 上传图片显示扫描效果html5,JS+HTML5实现上传图片预览效果完整实例【测试可用】...
  5. size-t数据类型 ssize-t数据类型
  6. Winform中实现点击按钮弹窗输入密码验证通过后执行相应逻辑
  7. boost::graph模块实现在无向图上使用连通分量算法
  8. 前端学习(1531):钩子函数--代码演示(面试重点)二
  9. 【注册机】Zillions of Games v2.0.1p 注册机
  10. Android自定义View之上拉、下拉列表 头部元素跟随 缩放、平移效果的实现
  11. Linux 命令(56)—— telnet 命令
  12. 牛客网–华为机试在线训练6:质数因子
  13. oracle切换实例启动,3.1 Oracle体系结构之实例启动与关闭
  14. 【技术白皮书】第四章:信息抽取技术产业应用现状及案例(下)
  15. 在ext4文件系统上恢复被误删除的文件
  16. (转帖)Spring循环依赖的解决办法
  17. oracle ora-3136,ORA-3136 错误解决 .
  18. 安装最新版本zlib
  19. postman打不开的解决办法
  20. 详解unity中tranform.worldToLocalMatrix

热门文章

  1. 软件暴力破解的原理和破解经验
  2. 无需任何插件,教你影像如何精准导入CAD软件进行绘图?
  3. 微信红包封面,你真的领取到了吗?
  4. 图像处理笔记——边缘检测算子
  5. 丢花娟(约瑟夫环问题)
  6. 计算机掌握录音机的使用方法,如何使用2种方法从计算机录制音频
  7. Windows 技术篇 - win10系统更新后切换应用一直自动切换为微软输入法解决方法,win10微软输入法卸载方法
  8. java 汉字 拼音排序_Java字符串按照汉语拼音排序
  9. C语言 分支语句:if 语句和 switch语句
  10. android录制视频设置分辨率,Android录制视频的全面屏适配