Rubyish way to invert regex

Suppose a regular expression comes from a call code outside the current context and then passes to another call that is implemented outside the current project:

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

Is there a simple Ruby way to achieve the following behavior when making a call?

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

This behavior is similar to switching the operator =~ with the operator !~ . Of course, you can use #select or #reject or open or subclass Regexp . But I'm curious if there is a way already available in Ruby to deny matches returned by the regex as described above. Also, I don't care if false or nil or true , or the matching position is involved to fulfill this effect.

There is a theoretical question that matters, but that goes beyond simple considerations.


EDIT : I understand that iterators are a common way to go into Ruby to filter a list, but people ignore the limitations of the question. Also, I think there is something good functioning about how regex is upside down. I do not see it to be half excessive or too smart; it is simple object-oriented programming and what Ruby excels at the same time.

+4
source share
5 answers

You can do something like this:

 class NegatedRegex < Regexp def ===(other) !super end end class Regexp def negate NegatedRegex.new self end end 

There are probably other methods for overriding, but for grep, this is enough:

 ["1", "2"].grep(/1/.negate) #=> ["2"] 
+3
source
 ["1", "2"].reject { |e| /1/ === e } 
+6
source

You can do them in one go:

 re = /1/ matches, non_matches = ["1", "2", "1", "3"].partition { |el| re =~ el } p matches #=> ["1", "1"] p non_matches #=> ["2", "3"] 
+3
source
 arr=["1","2"] arr-arr.grep("1") # ["2"] 

:)

+1
source

This may be one way to do this.

 ["1", "2", 3].select {|i| i !~ /1/ } => ["2", 3] 
+1
source

Source: https://habr.com/ru/post/1491486/


All Articles