带有通配符的正则表达式负向外观

Kev*_*der 8 ruby regex lookbehind

我试图匹配一些文本,如果它附近没有另一个文本块.例如,"bar"如果"foo"不在它之前,我想匹配.我可以匹配"bar"如果在此正则表达式中使用负面外观后"foo"立即在它之前:

/(?<!foo)bar/
Run Code Online (Sandbox Code Playgroud)

但我也不喜欢"foo 12345 bar".我试过了:

/(?<!foo.{1,10})bar/
Run Code Online (Sandbox Code Playgroud)

但使用通配符+范围似乎是Ruby中的无效正则表达式.我在想这个问题错了吗?

Mar*_*der 12

你正在考虑正确的方法.但不幸的是,后视镜通常具有固定长度.唯一的主要例外是.NET的正则表达式引擎,它允许在lookbehinds内部重复量词.但是,因为你只需要一个消极的外观,而不是前瞻.有一个黑客为你.反转字符串,然后尝试匹配:

/rab(?!.{0,10}oof)/
Run Code Online (Sandbox Code Playgroud)

然后反转匹配的结果或从字符串的长度中减去匹配位置,如果这就是你所追求的.

现在从你给出的正则表达式,我想这只是你实际需要的简化版本.当然,如果bar一个复杂的模式本身,需要更多的思考如何正确地扭转它.

请注意,如果您的模式需要可变长度的lookbehinds和lookaheads,那么解决这个问题会更难.此外,在您的情况下,可以将您的lookbehind解构为多个可变长度的(因为您既不使用也不+*):

/(?<!foo)(?<!foo.)(?<!foo.{2})(?<!foo.{3})(?<!foo.{4})(?<!foo.{5})(?<!foo.{6})(?<!foo.{7})(?<!foo.{8})(?<!foo.{9})(?<!foo.{10})bar/
Run Code Online (Sandbox Code Playgroud)

但那不是那么好,是吗?