正则表达式-非获取匹配(非捕获),正向预查,负正向预查,反向预查

来源:www.zhile.name 更新时间:2023-05-25 21:55

关于正则这篇文章讲的比较好。https://www.wodecun.com/blog/8012.html
在使用正则表达式的时候,我们经常会使用括号()把某个部分括起来,称为一个子模式。

子模式有CapturingNon-Capturing两种情况。

  • Capturing指获取匹配,是指系统会在幕后将所有的子模式匹配结果保存起来,供我们查找或者替换。如后向引用的使用;

  • 而Non-Capturing指非获取匹配 ,这时系统并不会保存子模式的匹配结果,子模式的匹配更多的只是作为一种限制条件使用,如正向预查,反向预查,负正向预查,负反向预查等。

后向引用

使用"数字"代表前面某个子模式的匹配内容

我们使用正则表达式,在很多场景下的作用是为了查找和替换,大部分语言的正则表达式实现中,在查找时,使用后向引用来代表一个子模式,语法是"数字",而在替换中,语法是"$数字"。
在正则表达式中,我们可以使用 "数字 " 来进行后向引用,数字表示这里引用的是前面的第几个子模式。如下:

Text

  1. <h1>This is a valid header</h1>
  2. <h2>This is not valid.</h3>

RegEx

  1. <h([1-6])>.*?</h1 >

Result

  1. <h1>This is a valid header</h1>

上面示例中,1代表前面的子模式([1-6])的匹配结果 1,所以不符合的匹配<h2>..</h3>并没有被匹配。

后向引用常见的应用常见是:

  • 匹配重复单词 (w+) 1
  • 匹配合法的html标记,如上例。

非获取匹配

在子模式内部前面添加"?:"

非获取匹配表示这个子模式的匹配内容不会被保存,不能用于后向引用中。简单说,非获取匹配就是只匹配,不保存。看个例子:

Text

  1. Windows 95 and Windows 98 are the successor.
  2. Then Windows 2000 and Windows Xp appeared.
  3. Windows Vista is the Latest version of the family.

RegEx

  1. Windows (?:[w]+b)

Result

  1. Windows 95
  2. Windows 98
  3. Windows 2000
  4. Windows Xp
  5. Windows Vista

在这个例子中,子模式(?:[w]+b)是一个非获取匹配,只匹配内容,但并未保存字匹配的结果。

正向预查

在子模式的内部前面添加"?="

正向预查的意思是,子模式仅仅作为条件限制,并不作为匹配结果输出,子模式前面的。

Text

  1. Windows 95 and Windows 98 are the successor.
  2. Then Windows 2000 and Windows Xp appeared.
  3. Windows Vista is the Latest version of the family.

RegEx

  1. Windows(?= [d]+b)

Result

  1. Windows
  2. Windows
  3. Windows

这个例子中,要获取所有后面带有数字的Windows字符串。子模式在这里仅仅作为一个限制条件使用,仅参与匹配过程,并不作为匹配结果输出。

负正向预查

负正向预查的作用正好与正向预查相反,语法为在子模式内部前面增加"?!"。

比如上面例子,如果RegEx为Windows(?! [d]+b),则匹配的结果会是Windows XpWindows Vista中的Windows

反向预查

在子模式的内部前面添加"?<="

反向预查与正向预查很相似,子模式仅仅作为条件限制,不作为结果输出,唯一的不同是,正向预查匹配子模式前面的结果作为匹配结果,而反向预查匹配子模式后面的结果作为匹配结果。看个例子:

Text

  1. CNY:100.2
  2. USD:222.1
  3. CNY:301.3
  4. HKD:122.1
  5. CNY:114.4

RegEx

  1. (?<=CNY:)d+.d

Result

  1. 100.2
  2. 301.3
  3. 114.4

这个例子里,要获取属于CNY的金额。子模式仅参与匹配过程,并不作为匹配结果输出。

负反向预查

负反向预查的作用正好与反向预查相反,语法为在子模式内部前面增加"?<!"。

比如上面例子,如果RegEx为(?<!CNY:)bd+.d,则会获取不属于CNY金额