我需要匹配以"bar"
结尾但不以"foo"
开头的数组成员,并将结果放入新数组中。
查看1.9.3和2.0.0的文档,它们似乎支持使用相同语法的负面预测。负面的预测工作正如我在ruby 2.0.0中预期的那样,但似乎在ruby 1.9.3中不起作用:
["foo a.bar", "b.bar"].grep(/(?!^foo\s).*\.bar$/)
# => ["b.bar"] (ruby 2.0.0)
# => ["foo a.bar", "b.bar"] (ruby 1.9.3)
此基础架构上的ruby版本将在4个月内升级,但不能更快地更改版本。我怎样才能在1.9.3中完成这项工作,最好继续在2.0中工作?
答案 0 :(得分:7)
更好地使用它,看起来更有说服力:
matched = array.grep(/^(?!foo\s).*\.bar$/)
NOT
以foo开头
这将适用于2.1.1和1.9.3
只有你想知道我做了什么:
# ruby-1.9.3-p362
array = ["foo a.bar", "b.bar"]
# => ["foo a.bar", "b.bar"]
matched = array.grep(/(?!^foo\s).*\.bar$/)
# => ["foo a.bar", "b.bar"]
matched = array.grep(/^(?!foo\s).*\.bar$/)
# => ["b.bar"]
matched = array.grep(/(?!^foo\s).*\.bar$/)
# => ["foo a.bar", "b.bar"]
# ruby-2.1.1
array = ["foo a.bar", "b.bar"]
# => ["foo a.bar", "b.bar"]
matched = array.grep(/(?!^foo\s).*\.bar$/)
# => ["b.bar"]
matched = array.grep(/^(?!foo\s).*\.bar$/)
# => ["b.bar"]
答案 1 :(得分:4)
如果在生产服务器上绑定的ruby版本中似乎存在问题,那么简单的解决方案就是不使用负面预测。如果您的示例足够特别,您可以使用select
和方便的String方法:
array.select {|str| !str.starts_with?('foo') && str.ends_with?('bar') }
答案 2 :(得分:3)
这是你的正则表示错误,而不是Ruby。 Ruby 2似乎有点宽容,是全部。
起始锚点(^
)应该是之前的,而不是它。当它在行的开头不匹配foo
时,正则表达式引擎向前突然移动一个位置并再次尝试。它不再是字符串的开头,因此^
不匹配,否定前瞻报告成功,正则表达式匹配oo a.bar
。 (这是一个非常常见的错误。)