宝哥软件园

正则表达式零宽度断言的详细说明

编辑:宝哥软件园 来源:互联网 时间:2021-09-13

正则表达式零宽度断言:

零宽度断言是正则表达式中的一个难点,因此本章重点分析匹配原理。零宽度断言还有其他名称,如“环顾四周”或“预搜索”,但这些都不是我们关注的焦点。

一、基本概念33-360

零宽度断言,就像它的名字一样,是一种零宽度匹配。它匹配的内容不会保存在匹配结果中,最终的匹配结果只是一个位置。功能是在指定位置添加限定条件,指定该位置前后的字符必须满足限定条件,才能使正则表达式中的单词匹配成功。请注意,这里提到的子表达式不仅是括在括号中的表达式,而且是正则表达式中任意匹配的单位。Javascript只支持零宽度预断言,可分为正零宽度预断言和负零宽度预断言。

代码示例如下:

示例代码一:

var str=' abZW863var reg=/ab(?=[A-Z])/;console . log(str . match(reg));在上面的代码中,正则表达式的语义是:匹配字符串' ab '后跟任何大写字母。最终的匹配结果是“ab ”,因为零宽度断言“(?=[A-Z])“不匹配任何字符,但用于指定当前位置必须后跟大写字母。

示例代码二:

var str=' abZW863var reg=/ab(?[A-Z])/;console . log(str . match(reg));在上面的代码中,正则表达式的语义是:匹配不跟任何大写字母的字符串' ab '。正则表达式未能匹配任何字符,因为ab后面是字符串中的大写字母。

二.匹配原则:

上面的代码只介绍了零宽度断言在概念上是如何匹配的。下面描述了匹配原则如何匹配正零宽度断言和负零宽度断言。1.正零宽度断言:代码示例如下:

var str=' divantzonevar reg=/^(?=)[^] w/;console . log(str . match(reg));

匹配过程如下:首先,从正则表达式中的“”获取控制权。首先,从位置0开始匹配。它与起始位置0匹配。匹配成功,控制权转移到'(?=)',因为''是零宽,所以'(?=)”也从位置0匹配。它要求位置0的右侧必须是字符“”,位置0的右侧恰好是字符“”。匹配成功,控制权转移到“”,因为“(?=)'也是零宽度,所以也是从位置0开始匹配,所以匹配成功,后面的匹配过程就不介绍了。

2.负零宽度断言:

代码示例如下:

var str=' abZW863ab88var reg=/ab(?[A-Z])/g;console . log(str . match(reg));

匹配过程如下:首先从正则表达式的字符‘a’获取控制权,从位置0开始匹配,匹配成功后将控制权转移到‘b’,从位置1开始匹配,匹配成功后将控制权转移到’(?[A-Z])’,它从位置2开始匹配。它要求仓位的右侧不能是任何大写字母,但是仓位的右侧是大写字母‘z’。匹配失败,然后控制权再次交给字符‘a’,匹配失败,然后控制权再次交给字符‘a’,但还是失败,所以重复。【A-Z】)’,它从位置9开始尝试匹配,它规定其位置的右侧不能是大写字母,匹配成功,但并没有真正匹配字符,所以最终匹配结果是‘ab’。

以下是补充

零宽度断言是正则表达式中的一种方法。在计算机科学中,正则表达式指的是用于描述或匹配符合特定句法规则的一系列字符串的单个字符串。

定义解释

零宽度断言是正则表达式中的一种方法。在计算机科学中,正则表达式指的是用于描述或匹配符合特定句法规则的一系列字符串的单个字符串。在许多文本编辑器或其他工具中,正则表达式通常用于检索和/或替换符合特定模式的文本内容。许多编程语言支持使用正则表达式进行字符串操作。例如,一个强大的正则表达式引擎内置在Perl中。正则表达式的概念最早是由Unix中的工具推广的,比如sed和grep。正则表达式通常缩写为“regex”,有单数regexp和regex,复数regexps、regexes和regexen。

零宽度断言

用来查找某些内容(但不包括这些内容)之前或之后的东西,也就是说,用来指定一个像 b、$,应该满足一定条件的位置(即断言),所以也叫零宽度断言。最好举个例子:断言是用来声明一个应该为真的事实。在正则表达式中,只有当断言为真时,匹配才会继续。

(?=exp)也称为零宽度前向预测高级断言,它断言表达式exp可以在它出现的位置后面匹配。例如b(?=re)w b,匹配以re开头的单词的后面部分(re除外),例如,在寻找重新阅读一本书时。它将匹配丁。

var reg=new Regex(@'w(?=ing)');var str=' muing控制台。WriteLine(reg。匹配(字符串)。价值);//返回mu(?=exp),也称为零宽度前向审查后断言,断言其位置的前面可以匹配表达式exp。例如bw(?=ingb)匹配以ing结尾的单词的前半部分(ing除外),例如,在查找“我正在阅读”时,它匹配read。

如果你想在一个长数字的每三个数字之间加一个逗号(当然是从右边开始),你可以寻找需要在前面和里面加逗号的部分:(?=d)d{3}) b,用它查找1234567890时,结果是234567890。以下示例使用了这两种断言:(?=s)d(?=s)匹配由空白字符分隔的数字(同样,这些空白字符不包括在内)。

负零宽度断言

我们前面提到了如何找到不是字符或者不在字符类中的字符(反义)。但是,如果我们只想确保某个角色不会出现,但又不想与之匹配,该怎么办?例如,如果我们想找到一个单词,其中有字母q,但q后面没有字母u,我们可以尝试这样做:

b w * q [u] w * b匹配包含字母q但后面没有字母u的单词,但是如果你做更多的测试(或者如果你足够敏锐直接观察),你会发现如果q出现在一个单词的末尾,比如伊拉克、明基明基,这个表达就会出错。这是因为[u]总是匹配一个字符,所以如果q是一个单词的最后一个字符,那么下面的[u]将匹配q后面的单词分隔符(可能是空格、句点之类的),下面的w*b将匹配下一个单词,所以 b w * q [u] 。负零宽度断言可以解决这个问题,因为它只匹配一个位置,不消耗任何字符。现在,我们可以这样解决这个问题:bw*q(?u)w*b .

零宽度负预测第一个断言(?Exp),断言表达式exp不能在此位置后匹配。示例:d{3}(?d)匹配三位数字,这三位数字后面不能跟数字;b((?Abc)w) b匹配不包含连续字符串Abc的单词。同理,我们可以用(?Exp),零宽度负面评论后面是断言,断言这个位置的前面不能匹配表达式exp:(?[a-z])d{7}匹配前面没有小写字母的七位数字。

更复杂的例子:(?=(w))。*(?=/1)匹配没有属性的简单HTML标记内的内容。(?=(w))指定这样一个前缀:一个用尖括号括起来的单词(例如,它可能是),后跟。*(任意字符串),最后是后缀(?=/1)。注意后缀中的/使用前面提到的字符转义;1是反向引用,指的是捕获的第一组,和前面的(w)匹配的内容,这样如果前缀是实际的,后缀就是它。整个表达式匹配和之间的内容(同样,前缀和后缀本身不包括在内)。

看了上面的有点伤脑筋。下面我们再补充一点

断言用于声明一个事实,这个事实应该是真实的。在正则表达式中,只有当断言为真时,匹配才会继续。接下来的四个用来查找某些内容(但不包括这些内容)之前或之后的东西,也就是说用来指定一个像 b、$,应该满足一定条件(即断言)的位置,所以也叫零宽度断言。不如举个例子来说明。=exp)也称为零宽度前向预测高级断言,它断言表达式exp可以在它出现的位置后面匹配。例如bw(?=ingb),匹配以ing结尾的单词的前部(ing除外),例如,当寻找我在唱歌而你在跳舞时,它将匹配sing和danc。(?=exp),也称为零宽度前向审查后断言,断言其位置的前面可以匹配表达式exp。例如(?=bre)w b匹配以re开头的单词的后半部分(re除外),例如,在查找阅读书籍时,它匹配阅读。

如果你想在一个长数字的每三个数字之间加一个逗号(当然是从右边开始),你可以寻找需要在前面和里面加逗号的部分:(?=d)d{3})*b,用它查找1234567890时,结果是234567890。以下示例使用了这两种断言:(?=s)d(?=s)匹配由空白字符分隔的数字(同样,这些空白字符不包括在内)。

补编2:

最近,为了处理html文件的源代码,需要定期搜索和替换。所以我借此机会学习了规律性系统。虽然之前用的是规律性,但每次都是临时学的。在学习的过程中,我还是遇到了很多问题,尤其是零宽度的断言(这里,我不得不吐槽一下。网上有所有复制粘贴的内容。遇到问题的时候查了很多重复的东西。流汗!),所以在这里写下你的理解供以后参考!

零宽度前向预测的第一个断言是什么?看看msdn上的官方解释定义

(?=子表达式)

(零宽度前向预测第一个断言。)仅当子表达式在此位置的右侧匹配时才继续匹配。例如,w(?=d)匹配后跟数字的单词,但不匹配数字。

经典例子:一个单词以ing结尾,所以在ing之前获取内容

var reg=new Regex(@'w(?=ing)');var str=' muing控制台。WriteLine(reg。匹配(字符串)。价值);//返回mu。以上是一个在互联网上随处可见的例子。在这里您可能会理解,exp表达式之前的内容被返回。

请看下面的代码

var reg=new Regex(@'a(?=b)c’;var str=' abc控制台。WriteLine(reg。IsMatch(str));//返回false。为什么它返回false?

其实msdn的官方定义已经说过了,但是很官方。这里需要注意一个关键点:这个位置。是的,这是一个位置,不是一个角色。然后结合官方定义和第一个例子来理解第二个例子:

因为A后面跟着B,所以此时返回匹配内容A(如第一个示例所知,只返回A,不返回exp匹配内容),A(?=b)c中的a(?Part=b)已经解决了,那么c的匹配问题也应该解决了。此时,c应该从字符串abc中匹配到哪里?结合官方的定义,我们知道它从子表达式的位置向右开始,也就是从b的位置开始,但是b不匹配a(?=b)c的其余部分,所以abc不匹配a(?=b)c.

那么要想和上面匹配,应该如何写正则呢?

答案是:a(?=b)bc

当然,有人会说abc直接匹配。你还得这么做吗?当然,你不必这样做,只是为了解释零宽度前向预测的第一个断言是什么?同样的原则也适用于其他零宽度断言!

补编三

(?=exp):零宽度前向预测预断言,它断言自身后面的位置可以匹配表达式exp。

# match后面是_path,结果是product' product _ path '。扫描/(产品)(?=_路径)/

(?=exp):零宽度向前查看延迟断言,它断言它出现的位置的前面可以匹配表达式exp

#比赛以名字:开头,结果是王菲的名字3360王菲。扫描/(?=name:)(王菲)/#王菲

(?Exp):零宽度负预测提前断言,断言表达式Exp在此位置后无法匹配。

# match后面没有_ path“product _ path”。扫描/(产品)(?_path)/#nil#匹配后面没有_ URL“product _ path”。扫描/(产品)(?_ URL)/#产品

(?Exp):零宽度负面评论和后断言,断言此位置的前面不能匹配表达式Exp

#匹配前面没有名称:“名称3360angelica”。扫描/(?名称:)(angelica)/#nil#匹配前面没有nick _ name 3360“name 3360 Angelica”。扫描/(?nick _ name :)(angelica)/# angelica

边肖也受够了这个东西。当有好的东西可以分享时,今天就洗洗睡吧

更多资讯
游戏推荐
更多+