正则表达式 之 断言详解

这篇具有很好参考价值的文章主要介绍了正则表达式 之 断言详解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

正则表达式的先行断言和后行断言一共有 4 种形式:

  • (?=pattern) 零宽正向先行断言(zero-width positive lookahead assertion)
  • (?!pattern) 零宽负向先行断言(zero-width negative lookahead assertion)
  • (?<=pattern) 零宽正向后行断言(zero-width positive lookbehind assertion)
  • (?<!pattern) 零宽负向后行断言(zero-width negative lookbehind assertion)

这里面的 pattern 是一个正则表达式。

如同 ^ 代表开头,$ 代表结尾,\b 代表单词边界一样,先行断言和后行断言也有类似的作用,它们只匹配某些位置,在匹配过程中,不占用字符,所以被称为"零宽"。所谓位置,是指字符串中(每行)第一个字符的左边、最后一个字符的右边以及相邻字符的中间(假设文字方向是头左尾右)。

下面分别举例来说明这 4 种断言的含义。

(?=pattern) 正向先行断言

代表字符串中的一个位置,紧接该位置之后的字符序列能够匹配 pattern。

例如对 "a regular expression" 这个字符串,要想匹配 regular 中的 re,但不能匹配 expression 中的 re,可以用 re(?=gular),该表达式限定了 re 右边的位置,这个位置之后是 gular,但并不消耗 gular 这些字符。

正则表达式 之 断言详解,正则表达式

将表达式改为 re(?=gular).,将会匹配 reg,元字符 . 匹配了 g,括号这一砣匹配了 e 和 g 之间的位置。

正则表达式 之 断言详解,正则表达式

(?!pattern) 负向先行断言

代表字符串中的一个位置,紧接该位置之后的字符序列不能匹配 pattern。

例如对 "regex represents regular expression" 这个字符串,要想匹配除 regex 和 regular 之外的 re,可以用 re(?!g),该表达式限定了 re 右边的位置,这个位置后面不是字符 g

负向和正向的区别,就在于该位置之后的字符能否匹配括号中的表达式。

正则表达式 之 断言详解,正则表达式

(?<=pattern) 正向后行断言

代表字符串中的一个位置,紧接该位置之前的字符序列能够匹配 pattern。

例如对 regex represents regular expression 这个字符串,有 4 个单词,要想匹配单词内部的 re,但不匹配单词开头的 re,可以用 (?<=\w)re,单词内部的 re,在 re 前面应该是一个单词字符。

之所以叫后行断言,是因为正则表达式引擎在匹配字符串和表达式时,是从前向后逐个扫描字符串中的字符,并判断是否与表达式符合,当在表达式中遇到该断言时,正则表达式引擎需要往字符串前端检测已扫描过的字符,相对于扫描方向是向后的。

正则表达式 之 断言详解,正则表达式

(?<!pattern) 负向后行断言

代表字符串中的一个位置,紧接该位置之前的字符序列不能匹配 pattern。

例如对 "regex represents regular expression" 这个字符串,要想匹配单词开头的 re,可以用 (?<!\w)re。单词开头的 re,在本例中,也就是指不在单词内部的 re,即 re 前面不是单词字符。当然也可以用 \bre 来匹配。

正则表达式 之 断言详解,正则表达式

对于这 4 个断言的理解,可以从两个方面入手:

  • 1、关于先行(lookahead)和后行(lookbehind):正则表达式引擎在执行字符串和表达式匹配时,会从头到尾(从前到后)连续扫描字符串中的字符,设想有一个扫描指针指向字符边界处并随匹配过程移动。先行断言,是当扫描指针位于某处时,引擎会尝试匹配指针还未扫过的字符,先于指针到达该字符,故称为先行。后行断言,引擎会尝试匹配指针已扫过的字符,后于指针到达该字符,故称为后行。

  • 2、关于正向(positive)和负向(negative):正向就表示匹配括号中的表达式,负向表示不匹配。

对这 4 个断言形式的记忆:

  • 1、先行和后行:后行断言 (?<=pattern)、(?<!pattern) 中,有个小于号,同时也是箭头,对于自左至右的文本方向,这个箭头是指向后的,这也比较符合我们的习惯。把小于号去掉,就是先行断言。

  • 2、正向和负向:不等于 (!=)、逻辑非 (!) 都是用 !号来表示,所以有 ! 号的形式表示不匹配、负向;将 ! 号换成 = 号,就表示匹配、正向。

我们经常用正则表达式来检测一个字符串中包含某个子串,要表示一个字符串中不包含某个字符或某些字符也很容易,用 [^...] 形式就可以了。要表示一个字符串中不包含某个子串(由字符序列构成)呢?

用 [^...] 这种形式就不行了,这时就要用到(负向)先行断言或后行断言、或同时使用。

例如判断一句话中包含 this,但不包含 that

包含 this 比较好办,一句话中不包含 that,可以认为这句话中每个字符的前面都不是 that 或每个字符的后面都不是 that。正则表达式如下:

^((?<!that).)*this((?<!that).)*$
或 
^(.(?!that))*this(.(?!that))*$

对于 this is runoob test 这句话,两个表达式都能够匹配成功,而 this and that is runoob test 都匹配失败。

正则表达式 之 断言详解,正则表达式

正则表达式 之 断言详解,正则表达式

在一般情况下,这两个表达式基本上都能够满足要求了。考虑极端情况,如一句话以 that 开头、以 that 结尾、that 和 this 连在一起时,上述表达式就可能不胜任了。 如 runoob thatthis is the case 或者 this is the case, not that 等。

只要灵活运用这几个断言,就很容易解决:

^(.(?<!that))*this(.(?<!that))*$
^(.(?<!that))*this((?!that).)*$
^((?!that).)*this(.(?<!that))*$
^((?!that).)*this((?!that).)*$

这 4 个正则表达式测试上述的几句话,结果都能够满足要求。

上述 4 种断言,括号里的 pattern 本身是一个正则表达式。但对 2 种后行断言有所限制,在 Perl 和 Python 中,这个表达式必须是定长(fixed length)的,即不能使用 *、+、? 等元字符,如 (?<=abc) 没有问题,但 (?<=a*bc) 是不被支持的,特别是当表达式中含有|连接的分支时,各个分支的长度必须相同。之所以不支持变长表达式,是因为当引擎检查后行断言时,无法确定要回溯多少步。Java 支持 ?、{m}、{n,m} 等符号,但同样不支持 *、+ 字符。Javascript 干脆不支持后行断言,不过一般来说,这不是太大的问题。

先行断言和后行断言某种程度上就好比使用 if 语句对匹配的字符前后做判断验证。

以下列出 ?=、?<=、?!、?<!= 的使用

exp1(?=exp2):查找 exp2 前面的 exp1。

正则表达式 之 断言详解,正则表达式

(?<=exp2)exp1:查找 exp2 后面的 exp1。

正则表达式 之 断言详解,正则表达式

exp1(?!exp2):查找后面不是 exp2 的 exp1。

正则表达式 之 断言详解,正则表达式

(?<!=exp2)exp1:查找前面不是 exp2 的 exp1。

正则表达式 之 断言详解,正则表达式文章来源地址https://www.toymoban.com/news/detail-682290.html

到了这里,关于正则表达式 之 断言详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • shell 正则表达式详解

    目录 正则表达式 一,什么是正则表达式 二,为什么使用正则表达式 三,如何使用正则表达式 示例: 四,基本正则表达式 基本正则表达式示例: 正则表达式字符集示例: 五,扩展正则表达式 扩展正则表达式示例: 扩展:        正则表达式是通过一些特殊字符的排列,

    2024年01月17日
    浏览(37)
  • MySQL正则表达式 | 事务详解

    目录 一、正则表达式 实例操作 二、事务 事务控制语句 MYSQL 事务处理主要有两种方法 SQL测试代码 PHP中使用事务实例 使用保留点 SAVEPOINT MySQL可以通过  LIKE ...%  来进行模糊匹配。 MySQL 同样也支持其他正则表达式的匹配, MySQL中使用 REGEXP 操作符来进行正则表达式匹配。 如果

    2023年04月18日
    浏览(28)
  • python 之正则表达式详解

    分清字符串与字符 在Python中,前缀 r 或 R 表示原始字符串。这种原始字符串中的反斜杠字符 被视为普通字符,而不是转义字符。这在处理正则表达式、文件路径等需要保留反斜杠原始含义的情况下非常有用。 原始字符串的特点: 反斜杠不进行转义: 在普通字符串中,反斜

    2024年02月06日
    浏览(39)
  • 详解正则表达式匹配方法 match()

    在前端开发中,正则表达式是一大利器。所以我们这次就来讨论下match()方法。 match本身是JavaScript语言中字符串对象的一个方法,该方法的签名是 match([string] | [RegExp]) 它的参数既可以是一个字符串,也可以是一个正则表达式。该方法绝大多数都是要使用正则表达式的,所以参

    2024年02月11日
    浏览(41)
  • 前端系列:正则表达式RegExp详解

    字面量创建 构造函数 字符串方法 match:返回一个字符串匹配正则表达式的结果,如果未找到匹配则为 null search:返回正则表达式在字符串中首次匹配项的 索引 ;否则,返回 -1 replace:返回一个由替换值( replacement )替换部分或所有的模式( pattern )匹配项后的新字符串。模式可以

    2024年02月02日
    浏览(57)
  • 身份证号码正则表达式详解

    公民身份号码是特征组合码,由十七位数字本体码和一 位 校验码 组成 。排列顺序从左至右依次为:六位数字地址码,八位数字出生日期码,三位数字顺序码和一位数字校验码。 地址码 : ( 身份证号码第一位到第六位 ) 表示编码对象常住户口所在 的 行政区划代码,按

    2024年02月06日
    浏览(31)
  • 详解Python正则表达式(含丰富案例)

    前言:正则表达式在网络爬虫、数据分析中有着广泛使用,掌握正则表达式能够达到事半功倍的效果。本文详细介绍正则表达式中各种规则及其符号含义,并结合Python中的Re库进行演示,由浅入深,即学即练即用,内容丰富,非常适合初学者。 正则表达式( regular expression )

    2024年02月03日
    浏览(23)
  • 【23JavaScript 正则表达式】深入解析JavaScript正则表达式:基础概念、常用方法和实例详解,轻松掌握强大的文本模式匹配工具

    正则表达式是一种强大的文本模式匹配工具,用于在字符串中搜索和操作特定的文本模式。在JavaScript中,正则表达式提供了一种灵活的方式来处理字符串操作。 在JavaScript中,可以通过使用字面量表示法或RegExp对象来创建正则表达式。 字面量表示法 RegExp对象 JavaScript中的正则

    2024年02月08日
    浏览(50)
  • 正则表达式详解(零基础教学,手把手教你写正则)

    本篇文章将从零讲解什么是正则表达式,以及正则表达式的规则、在python中的应用,用通俗易懂的描述方式进行零基础级别的讲解,尽量做到全网最全讲解,力求最高质量文章,欢迎关注!点击目录可直接进行相关位置跳转。 目录: 什么是正则? 为什么需要正则? 元字符

    2023年04月08日
    浏览(32)
  • python中正则表达式的使用详解(相当全面)

    #正则表达式是什么? 它是约束字符串匹配某种形式的规则 #正则表达式有什么用? 1.检测某个字符串是否符合规则.比如:判断手机号,身份证号是否合法 2.提取网页字符串中想要的数据.比如:爬虫中,提取网站天气,信息,股票代码,星座运势等具体 正则只能匹配字符串格式,不

    2024年01月16日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包