正则表达式在给定字符之后忽略模式

regex to ignore patterns when after a given characterr

我正在尝试发现一种模式(在 Ruby 源代码文件中),但如果在内联注释中(即在 # 字符之后)找到该模式,则忽略该模式。

例如,给定这段文字 foo.bar foo foo::bar # foo.bar foo::bar

我希望捕获 foo 的第一个 (foo.bar) 和第三个 (foo::bar) 情况,而忽略其余情况(第二个没有立即尾随 .::,第四个和第五个出现在 # 之后,因此应忽略。

对于这篇文章, foo.bar foo foo::bar

它应该仍然以相同的方式选择第一个和第三个(因为没有要忽略的评论)。

我有各种各样的技术来解决这个问题,但没有一个能满足所有情况。 Lookbehind 很有前途,但无法处理我的正则表达式方言 (Ruby) 中的可变长度。

因此,((?<!\#.*)foo[\.|:{2}]) 将无法工作,因为它是可变长度的(而且,如所写,无论如何只会排除 # 之后的第一个实例)

(.+?(?=#)) 也很有前途,所以我尝试了 ((foo(\.|\:{2})).+)?(?=\#),这很接近,但看不出在第一个之后有 2 个 foo。匹配组只是 returns foo.bar foo foo::bar,但它会适当地忽略 # 之后的任何内容。我很确定是 .+ 导致了糟糕的区分,但对此的其他修正似乎并没有让我更接近。

显然,我不知道如何进行此操作,并开始怀疑这是否可能。

[编辑:添加了第二个示例]

我不在 Ruby 工作,但根据您的描述,Ruby 似乎不支持回顾中的无限量词。这当然使它变得更加困难。但是,您可以利用无限前瞻。您可以使用一个正则表达式来检查没有内嵌注释的 foo_bars:

^[^#]*foo(?:\.|::)bar(?=[^#]*$)

...和一个正则表达式,用于检查 foo_bar 是否具有内联注释:

foo(?:\.|::)bar(?=[^#]*#)

...然后将它们交替放在一起:

foo(?:\.|::)bar(?=[^#]*#)|^[^#]*foo(?:\.|::)bar(?=[^#]*$)