我正在尝试匹配一些文本,如果它在附近没有另一个文本块,则匹配成功。例如,如果"foo"
不在"bar"
之前出现,我想要匹配"bar"
。我可以使用这个正则表达式中的负向后顾断言来匹配"bar"
,如果"foo"
没有立即出现:
/(?<!foo)bar/
但我也希望不匹配"foo 12345 bar"
。我尝试了:
/(?<!foo.{1,10})bar/
使用通配符和范围似乎在Ruby中不是一个有效的正则表达式。我对这个问题的思考方式有误吗?
我正在尝试匹配一些文本,如果它在附近没有另一个文本块,则匹配成功。例如,如果"foo"
不在"bar"
之前出现,我想要匹配"bar"
。我可以使用这个正则表达式中的负向后顾断言来匹配"bar"
,如果"foo"
没有立即出现:
/(?<!foo)bar/
但我也希望不匹配"foo 12345 bar"
。我尝试了:
/(?<!foo.{1,10})bar/
你的想法是正确的。但不幸的是,回溯断言通常需要固定长度。唯一的主要例外是.NET的正则表达式引擎,它允许在回溯断言内使用重复量词。但由于你只需要负向回溯断言而不是正向回溯断言,所以有一个技巧可供你使用。反转字符串,然后尝试匹配:
/rab(?!.{0,10}oof)/
如果您想要的是将匹配位置从字符串长度中减去,那么请对匹配结果进行反转或减法操作。
根据您提供的正则表达式,我推测这只是您实际所需的简化版本。当然,如果bar
本身就是一个复杂模式,那么需要更多的思考来正确地进行反转。
请注意,如果您的模式需要变长回顾和前瞻,那么解决这个问题会更加困难。此外,在您的情况下,可以将您的回顾拆分为多个可变长度回顾(因为您既没有使用+
也没有使用*
):
/(?<!foo)(?<!foo.)(?<!foo.{2})(?<!foo.{3})(?<!foo.{4})(?<!foo.{5})(?<!foo.{6})(?<!foo.{7})(?<!foo.{8})(?<!foo.{9})(?<!foo.{10})bar/
但这还不太好,是吗?
string.match(/bar/) and !string.match(/foo.*bar/)
以下是需要翻译的内容:
将为您提供所需的示例。
如果您希望匹配成功的字符串为bar foo bar
,则可以使用以下方法:
string.scan(/foo|bar/).first == "bar"
bar foo bar
。原帖中尝试的正则表达式会检索到第一个 bar
。而你的解决方案则会认为没有匹配项。(除了你忽略了“最多10个字符”的启发式算法这一事实) - Martin Ender