4

假设一个正则表达式来自当前上下文之外的调用代码,然后被传递给在当前项目之外实现的另一个调用:

["1", "2"].grep(/1/)        #=> ["1"]

进行调用时,是否有一种简单的 Rubyish 方式来实现以下行为?

["1", "2"].grep(/1/.negate) #=> ["2"]

此行为类似于=~用运算符切换运算!~符。当然,可以使用#selector #reject,或者打开或子类化Regexp。但是我很好奇Ruby中是否已经有一种方法可以以上述方式否定正则表达式返回的匹配项。另外,我不在乎匹配的位置false是否涉及到实现此效果niltrue

有一个相关的理论问题,但超出了这里的简单考虑。


编辑:我知道迭代器是在 Ruby 中过滤列表的一般方法,但人们忽略了问题的约束。另外,我认为正则表达式被反转的方式有一些很好的功能。我不认为它过度劳累或过于聪明。它是陈旧的面向对象编程,也是 Ruby 擅长做的事情。

4

6 回答 6

6
["1", "2"].reject { |e| /1/ === e }
于 2013-07-15T16:59:37.847 回答
3

你可以这样做:

class NegatedRegex < Regexp
  def ===(other)
    !super
  end
end

class Regexp
  def negate
    NegatedRegex.new self
  end
end

可能还有其他方法可以重新实现,但对于 grep 这已经足够了:

["1", "2"].grep(/1/.negate) #=> ["2"]
于 2013-07-15T17:18:50.990 回答
3

您可以一次性完成它们:

re = /1/
matches, non_matches = ["1", "2", "1", "3"].partition { |el| re =~ el }

p matches       #=> ["1", "1"]
p non_matches   #=> ["2", "3"]
于 2013-07-15T18:49:15.873 回答
1
arr=["1","2"]
arr-arr.grep("1")  # ["2"]

:)

于 2013-07-15T17:16:24.217 回答
1

这可能是这样做的一种方式

["1", "2", 3].select {|i| i !~ /1/ }
 => ["2", 3] 
于 2013-07-15T17:46:17.527 回答
1

Grep 有一个黑暗的兄弟,他所做的一切都与 grep 相同,反之亦然。

["1", "2"].grep(/1/)   #=> ["1"]

["1", "2"].grep_v(/1/) #=> ["2"]
于 2021-09-07T18:10:48.167 回答