regex 理解被求反的字符类

u2nhd7ah  于 2023-05-08  发布在  其他
关注(0)|答案(3)|浏览(133)

正则表达式:

/''+[^f]/g

当应用于字符串时:

don't '''theater'''  but not'''d and not do'''f

也匹配do'''f中的三个撇号。为什么[^f]不排除它?
PS:我想找到连续的两个或两个以上的撇号后面跟着不是f。

3lxsmp7m

3lxsmp7m1#

+使regex引擎回溯,一旦在2个或更多'之后找到f。您可以在负前瞻中使用'替代方案来防止(为了不消耗除f'之外的字符,当您使用[^f]时,字符成为匹配的一部分,因为被否定的字符类是 * 消耗 * 模式,而lookaheads是零宽度Assert)。

''+(?!['f])

参见regex demo。这里,如果2个或更多的'符号后面跟着f',则(?!['f])将阻止匹配。此外,你也可以写一个限定量词{2,}(出现2次或更多次):'{2,}(?!['f])
如果你的正则表达式引擎支持 * 所有格量词 *,可以防止回溯到量化模式,使用一个:

''++(?!f)
  ^^

参见another demo(另一种写法是'{2,}+(?!f))。
如果你使用的.NET正则表达式库不支持所有格量词,你可以使用原子组(与所有格量词的工作方式相同,但适用于整个组):

(?>'{2,})(?!f)

参见.NET regex demo

wvmv3b1j

wvmv3b1j2#

因为撇号不是***f*
示例正则表达式匹配“至少有2个撇号后跟一个字符
不是f**”。

你看,最后一个匹配真的不包括那个f,而是撇号。所以如果你想排除最后一个匹配,你可能更喜欢这个正则表达式

''+[^'f]
3phpmpom

3phpmpom3#

你只需要一个atomic group,这样正则表达式就不会回溯到撇号,而撇号不是'f':

/(?>''+)[^f]/

你可以玩here
如果您的引擎支持possessive quantifiers,那么您也可以使用它们:

/''++[^f]/

如果你想接受任何既不是撇号也不是f的字符,那么你可以定义exclude只是另一个字符:

/''+[^'f]/

相关问题