关于python正则表达式中的否定预查

好久没写过东西了,水一点最近项目中接触比较多的关于正则的东西吧。
写正则的时候经常会遇到的一个问题是,如果我希望排除某种模式的时候该怎么做。如果是单个字符的话,我们自然可以用[^A-Z]之类的做法,但如果是比较复杂的模式呢?这就牵涉到否定预查。
之前有见过别人的正则里有?!这样的东西,以前并没有完全理解这个玩意儿,现在知道了,这就是否定预查。

 

正向否定预查(只查后面)

即使用?!,不过要注意,预查不占用字符,单独的?!无法匹配任何字符,后面需要加其他东西才行。

举个例子:

pat = 'x(?!:)' 

这里(?!:)不占用字符,后面没有东西,所以无法指向任何模式,因而只能匹配x

 

 再来一个:

pat = 'x(?!:).'

此处(?!:)指向后面的.,代表.可以是其他任何东西,但不能是:

 

 还有个例子:

pat = 'abc(?!(123))\d+'

此处(?!(123))指向后面的\d+,代表\d+可以是任何东西,但不能是123开头。

所以,总结一下,正向否定预查的结构基本上就是'(模式A)(?!(否定模式B))(模式C)',理解的时候可以按照'(模式A)(模式C)'来理解,但这里的模式C是有条件的,即它可以是任何符合模式C的东西,但起始部分不能符合否定模式B
例如'abc(?!(123))\d+',我们可以当成'abc\d+'来理解,但这个\d+是有条件的,即可以是任何符合\d+的东西,但不能是123开头。
那有人可能要问,如果我只想排除123(完全符合,只有123),但可以是1234或者12345呢?给否定预查的条件加上结尾符号$即可:

pat = 'abc(?!(123)$)\d+'

 

 

反向否定预查(只查前面)

反向否定预查与正向否定预查是类似的,只不过?!变成了?<!,其结构是'(模式A)(?<!(否定模式B))(模式C)',理解的时候同样可以按照'(模式A)(模式C)'来理解,但这里的是有条件的换成了模式A,即它可以是任何符合模式A的东西,但末尾部分不能符合否定模式B

简单的例子:

pat = '\d+(?<!(123))abc'

 

此处(?!(123))指向前面的\d+,代表\d+可以是任何东西,但末尾部分不能是123
也就是说我们可以当成'\d+abc'来理解,但这个\d+是有条件的,即可以是任何符合\d+的东西,但不能是123结尾。
同样地,如果只想完全匹配123而不错杀4123这种的话,加个开头符号^即可:

pat = '\d+(?<!^(123))abc'

 

大体如此。部分内容参考了https://www.jianshu.com/p/8bf162425d83 

posted @ 2021-07-22 20:02  SilenceGTX  阅读(428)  评论(0编辑  收藏  举报