Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
反求正则表达式的rubysh方法_Ruby_Regex - Fatal编程技术网

反求正则表达式的rubysh方法

反求正则表达式的rubysh方法,ruby,regex,Ruby,Regex,假设正则表达式来自当前上下文之外的调用代码,然后被传递到当前项目之外实现的另一个调用: ["1", "2"].grep(/1/) #=> ["1"] 在打电话时,有没有一种简单、鲁比的方法来实现以下行为 ["1", "2"].grep(/1/.negate) #=> ["2"] 此行为类似于使用切换=~运算符~操作员。当然,也可以使用#选择或#拒绝,或者打开或子类Regexp。但是我很好奇Ruby中是否已经有一种方法可以用上面的方式否定正则表达式返回的匹配。此外,我

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

["1", "2"].grep(/1/)        #=> ["1"]
在打电话时,有没有一种简单、鲁比的方法来实现以下行为

["1", "2"].grep(/1/.negate) #=> ["2"]
此行为类似于使用
切换
=~
运算符~操作员。当然,也可以使用
#选择
#拒绝
,或者打开或子类
Regexp
。但是我很好奇Ruby中是否已经有一种方法可以用上面的方式否定正则表达式返回的匹配。此外,我不在乎是否
false
nil
true
或匹配的位置与实现此效果有关

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


编辑:我知道在Ruby中,迭代器是过滤列表的常用方法,但是人们忽略了问题的限制。另外,我认为正则表达式反转的方式有一些很好的功能。我不认为这是过度劳累或太聪明的一半;这是一种简单的面向对象编程,也是Ruby擅长做的事情

["1", "2"].reject { |e| /1/ === e }

:)

您可以这样做:

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

class Regexp
  def negate
    NegatedRegex.new self
  end
end

这可能是一种方法

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

您可以一次性完成这两项工作:

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

p matches       #=> ["1", "1"]
p non_matches   #=> ["2", "3"]

尽管在语义上不明显,但仔细想想,将正则表达式传递给
split
“匹配”所有不匹配的子字符串。我对Ruby还不太熟悉,无法根据这个来写一个答案,但我相信其他人也可以。你的问题有点矛盾,因为当你可以简单地修改迭代器时,用这种方式修改正则表达式是不鲁比的。“我想说的是,你试图实现的目标比鲁比语更完美。”萨瓦-我原则上不反对这一点。但是Ruby允许多种解决问题的方法。在这种情况下,我想继续使用一个我无法控制的方法(不一定是
#grep
),例如,它可能不接受块参数。我喜欢这个方法的古怪之处,但您使用的是
#reject
,我希望继续使用
#grep
(或其他一些我无法控制的方法)@tadman:我试图在将一个正则表达式从我的控制传递到一个方法(不一定是
#grep
)的约束范围内工作,仅此而已。我并不想难为你。可以通过编程方式指定
reject
的参数,其中
/1/
可以是一个变量,也可以像这样包装它:
def grep\u reject(regex);拒绝{e | regex==e};结束
如果您正在寻找一个超级通用的解决方案,那么听起来您有一个体系结构问题,在不同的关注点之间有太多的信息泄漏。您应该有一个过滤器对象,如果给定一个regexp,它会满足您的需要。任何暴露正确方法的对象都是合适的替代对象。“Ruby方法”是传入定义过滤行为的块,因此在本例中,
{e|e!regex.match(e)}
将封装您正在寻找的逻辑。@tadman-在不评论在这种特定情况下泄漏关注点的可能性的情况下,Ruby提供了另一种在正则表达式被实例化后操作它们的方法,即,
Regexp.union
。我不认为假设的否定方法在精神上有那么大的不同。沿着这些思路的东西可能是实现这一点的唯一方法。如果Ruby中没有内置的支持,我会接受这个答案(我觉得没有)。
String\35; scan
例如,直接在MRI上调用
rb\u reg\u search
。如果不重新实现每个可能需要regexp的方法,就无法改变这种行为。虽然这很聪明,但它可能太聪明了,这种聪明的做法几年后你会想要构建一个时间机器,回到过去,并阻止自己从一开始就这样做。也许它太聪明了,但我认为这很有趣,值得一试。我喜欢这种方法,但更安全的做法是不要将
Regexp
子类化(因为实际上并没有否定它的所有行为),而是使用一个只定义
==
的类。
["1", "2", 3].select {|i| i !~ /1/ }
 => ["2", 3] 
re = /1/
matches, non_matches = ["1", "2", "1", "3"].partition { |el| re =~ el }

p matches       #=> ["1", "1"]
p non_matches   #=> ["2", "3"]