Ruby 带有通配符的Regex负lookbehind

Ruby 带有通配符的Regex负lookbehind,ruby,regex,lookbehind,Ruby,Regex,Lookbehind,我试图匹配一些文本,如果它附近没有其他文本块。例如,如果“foo”前面没有,我想匹配“bar”。如果“foo”没有立即在它前面,我可以在这个正则表达式中使用反向查找来匹配“bar”: /(?<!foo)bar/ 但是在Ruby中使用通配符+a范围似乎是无效的正则表达式。我是不是想错了这个问题?你想得对。但不幸的是,lookbehind通常是固定长度的。唯一的主要例外是.NET的正则表达式引擎,它允许在lookbehind中使用重复量词。但因为你只需要消极的回顾,而不是前瞻。有一个黑客为你

我试图匹配一些文本,如果它附近没有其他文本块。例如,如果
“foo”
前面没有,我想匹配
“bar”
。如果
“foo”
没有立即在它前面,我可以在这个正则表达式中使用反向查找来匹配
“bar”

/(?<!foo)bar/

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

你想得对。但不幸的是,lookbehind通常是固定长度的。唯一的主要例外是.NET的正则表达式引擎,它允许在lookbehind中使用重复量词。但因为你只需要消极的回顾,而不是前瞻。有一个黑客为你。反转字符串,然后尝试匹配:

/rab(?!.{0,10}oof)/
然后反转匹配结果,或者从字符串长度中减去匹配位置,如果这是您想要的

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

请注意,如果您的模式同时需要可变长度lookbehind和lookahead,那么您将很难解决这个问题。此外,在您的情况下,可以将lookback分解为多个可变长度的lookback(因为您既不使用
+
也不使用
*
):

/(?

但这并不是很好,是吗?

正如m.buettner已经提到的,Ruby正则表达式中的lookbehind必须是固定长度的,并且在文档中也有描述。因此,不能在lookbehind中放置量词

您不需要在一个步骤中检查所有内容。尝试执行多个步骤的正则表达式匹配以获得所需内容。假设在单个
bar
实例前面存在
foo
,则无论是否存在另一个
bar
,都会破坏该条件,然后

string.match(/bar/) and !string.match(/foo.*bar/)
将为您提供您想要的示例

如果您希望通过
bar foo bar
成功匹配,则可以这样做

string.scan(/foo|bar/).first == "bar"

如果想法是实际检索匹配项,那么这是有问题的。假设您有
bar-foo-bar
。OP尝试的正则表达式将检索第一个
bar
。您的解决方案将声明不存在匹配项。(除了您省略了“最多10个字符”的启发式之外)@m、 buettner你和我对这个问题有不同的解释。当然。这就是为什么我没有说你的解决方案是错误的。但我发现陈述这些假设和差异是很重要的。因为他们可能对OP或将来发现这个问题的任何人都不明显。谢谢你阐明不同的解释ns.我接受@m.buettner的回复,因为这正是我所需要的。翻转字符串是一个有趣的想法。谢谢!
string.match(/bar/) and !string.match(/foo.*bar/)
string.scan(/foo|bar/).first == "bar"