好的,我的正则表达式是匹配鱼和青蛙,除非鱼或青蛙先于猫
/(?<!cat\s)f(ish|rog)/
的字符串:
foo catfish # match fish (want total non-match)
fooxcat fish # total non-match (yay)
foo cat frog # total non-match (yay)
foo cat fish # match fish (want total non-match)
foo cat frog # match frog (want total non-match)
foo dog fish frog # match fish and frog (yay)
fooxfish # match fish (yay)
foo frog # match frog (yay)
正如你所看到的,除非猫和青蛙/鱼之间有零个或多个空白字符,否则正则表达式完美无缺。所以从逻辑上讲,在我的负面观察中添加零个或多个空白字符应该可以解决这个问题:
/(?<!cat\s*)f(ish|rog)/
不幸的是,可变长度的外观无效。
如何将上述内容翻译成有效的正则表达式,或者是否有一个允许我使用可变长度后视镜的gem?
(更新青蛙到rog)
尝试失败:
(?<!cat\s)f(ish|rog)
(第一次尝试)
cat\s*f(?:ish|rog)\K|f(?:ish|rog)
(这一个非常接近,不幸的是它也匹配每条鱼/青蛙之后的空白)
答案 0 :(得分:4)
答案 1 :(得分:1)
以下是一些方法。
首先,进行测试:
def test
result =
[
['foo catfish', false],
['fooxcat fish', false],
['foo cat frog', false],
['foo cat fish', false],
['foo cat frog', false],
['foo dog fish frog', true ],
['fooxfish', true ],
['foo frog cat', true ],
].find { |str, res| check_it(str) != res }
result ? (puts result; false) : true
end
#1最简单的正则表达式
def check_it(str)
word = str[/cat|fish|frog/]
word && word != 'cat'
end
test #=> true
'cat'
必须是第一个!
#2分而治之
def check_it(str)
off = (str =~ /cat/)
off = str.size unless off
!!(str[0, off] =~ /fish|frog/)
end
test #=> true