正则表达式断言和分组捕获以及贪婪

正则的写法比较多,而且方法也很多,做到提取,替换,都需要不同的正则来

一,零宽断言(正向先行断言,负向先行断言,负向后行断言,正向后行断言)

  断言: 断定正则里面有什么字符

  零宽:就是欸有宽度,只匹配位置,不占字符,就是匹配结果不返回断言的正则本身

  通过提取字符例子来看:

   const string = "<span>阅读数量:345</span>"

   我现在通过不同的断言提取345

   1.  正向先行断言    

        语法: (?=pattern)

        作用:匹配pattern前面的内容,不返回自身

        我需要提取string 里面的345, 正向线性断言正则, 我现在就是需要拿到</span>前面的内容,可以有如下正则;

       let regexp = /.+(?=<\/span>)/g

      匹配 

      string.match(regexp) 得到 数组 如图

String.prototype.match 方法检索返回一个字符串匹配正则表达式的结果。

 

 但是我们只需要匹配数字,可以设置 \d+  如图

 

 

 

 

 

2. 正向后行断言(正后顾)

   语法:(?<=parttern)

   作用:匹配表达式后面的内容不返回自身  

   有了前面的正向先行匹配,这个就比较简单理解,可以写出如下正则

     const regexp = /(?<=<span>阅读数量:)\d+/g

   

 

 

3. 负向先行断言(复前瞻)

    语法:(?!parttern)

    作用:匹配非pattern前面的内容,不返回自身

 

   例如 str = '我爱祖国,我是祖国的花朵' ; 我要找到不是“的花朵”前面的祖国, 可以写出如下正则

 const regexp = /祖国(?!的花朵)/g

 

 

 

4. 负向后行断言

  语法: (?<!pattern)

  作用:匹配非pattern表达式后面的内容,不返回本身

 例如对 "regex represents regular expression" 这个字符串;要想匹配单词开头的 re

 const reg = /(?<!\w)re/ 匹配非w中的re

 

 

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

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

  • 先行和后行:后行断言 (?<=pattern)、(?<!pattern) 中,有个小于号,同时也是箭头,对于自左至右的文本方向,这个箭头是指向后的,这也比较符合我们的习惯。把小于号去掉,就是先行断言。
  • 正向和负向:不等于 (!=)、逻辑非 (!) 都是用 !号来表示,所以有 ! 号的形式表示不匹配、负向;将 ! 号换成 = 号,就表示匹配、正向。

 

二,捕获和非捕获

    也就是分组匹配

捕获组:匹配子表达式的内容,把匹配结果保存到内存中中数字编号或显示命名的组里,以深度优先进行编号,之后可以通过序号或名称来使用这些匹配结果。
 1. 数字编号捕获组(其实就是数字来放入表达式中)
 
语法:(exp)
解释:从表达式左侧开始,每出现一个左括号和它对应的右括号之间的内容为一个分组,在分组中,第0组为整个表达式,第一组开始为分组。
比如固定电话的:020-85653333
他的正则表达式为:(0\d{2})-(\d{8})
按照左括号的顺序,这个表达式有如下分组:

 我们用js 来验证一下:
 

 

 reg.exec可以提取到不同的分组, 例如028 , 88773322

 

 

2. 以此类推  命名编号捕获组: 

  拿到年月日

分组捕获电话号码, 使用match匹配正则会有一个数组, 以电话号码举例分别如下

 

在groups中可以通过命名正则上面的命名来获取捕获值

 

 

 

3. 非捕获组:
语法:(?:exp)
解释:和捕获组刚好相反,它用来标识那些不需要捕获的分组,说的通俗一点,就是你可以根据需要去保存你的分组。

 

还是匹配电话号码   如果不想要前面的区号  就在区号前面加?:

let phone2 = '027-99887766'.match(/(?:0\d{2})-(\d{8})/) 

 

 

 

三,反向引用

 

四, 贪婪和非贪婪

 贪婪: 尽可能多的匹配到符合条件的字符串

非贪婪:在贪婪量词后面加? 可以让贪婪正则变成懒惰正则   ?表示最小化匹配, 只能用在量词后面,表示如果多个文本段同时满足条件,则匹配最短的

例如匹配'<span></span> <span></span>'  包含几对’<span></span>‘呢 ,一般认为2个,实际上正则可以匹配到一整段了会

如果想不匹配整段,使用如下正则<span>.*?</span>

 

原作者姓名:假不理

原出处:掘金

原文链接:

 

 

 

 

posted @ 2022-08-18 11:52  大桥默默学  阅读(305)  评论(2编辑  收藏  举报