有没有办法在Ruby中将正则表达式捕获传递给块?

有没有办法在Ruby中将正则表达式捕获传递给块?,ruby,regex,block,Ruby,Regex,Block,我有一个散列,其中一个正则表达式作为键,一个块作为值。如下所示: { 'test (.+?)' => { puts $1 } } 显然不是这样,因为块被存储为Proc,但这就是想法 后来我有一个正则表达式匹配,看起来很像这样 hash.each do |pattern, action| if /#{pattern}/i.match(string) action.call end end 我们的想法是将块存储在散列中,以便于将来扩展,但现在正则表达式捕获没

我有一个散列,其中一个正则表达式作为键,一个块作为值。如下所示:

{ 'test (.+?)' => { puts $1 } }
显然不是这样,因为块被存储为Proc,但这就是想法

后来我有一个正则表达式匹配,看起来很像这样

hash.each do |pattern, action|
    if /#{pattern}/i.match(string)
        action.call
    end
end

我们的想法是将块存储在散列中,以便于将来扩展,但现在正则表达式捕获没有传递到块。有没有一种干净的方法可以支持我放入正则表达式中的任意数量的捕获,如中所示,某些正则表达式模式可能有1个捕获,其他模式可能有3个捕获?

如果将匹配数据传递到进程中会怎么样

hash.each do |pattern, action|
  if pattern.match(string)
    action.call($~)
  end
end
您的哈希将变成:

{ /test (.+?)/i => lambda { |matchdata| puts matchdata[1] } }

如果您将匹配数据传递到您的进程中呢

hash.each do |pattern, action|
  if pattern.match(string)
    action.call($~)
  end
end
您的哈希将变成:

{ /test (.+?)/i => lambda { |matchdata| puts matchdata[1] } }
我将使用Hash.find遍历散列元素,将它们传递到块中,一次一个。返回真值的人获胜:

大概是这样的:

hash = {/foo/ => lambda { 'foo' }, /bar/ => lambda { 'bar' } }
str = 'foo'
puts hash.find{ |n,v| str =~ n }.to_a.last.call
很明显,我用的是lambda,但距离足够近了。如果没有匹配项,则需要处理nil值。例如,我链接到了_a.last.call,但在现实生活中,你可能希望对nil做出反应,否则Ruby会发疯

如果您正在搜索大量的模式,或者处理大量的文本,那么每次都必须重新编译正则表达式,这会减慢您的搜索速度。我建议将密钥存储为regex对象以避免这种情况。

我将使用Hash.find,它遍历哈希元素,将它们传递到块中,一次一个。返回真值的人获胜:

大概是这样的:

hash = {/foo/ => lambda { 'foo' }, /bar/ => lambda { 'bar' } }
str = 'foo'
puts hash.find{ |n,v| str =~ n }.to_a.last.call
很明显,我用的是lambda,但距离足够近了。如果没有匹配项,则需要处理nil值。例如,我链接到了_a.last.call,但在现实生活中,你可能希望对nil做出反应,否则Ruby会发疯


如果您正在搜索大量的模式,或者处理大量的文本,那么每次都必须重新编译正则表达式,这会减慢您的搜索速度。我建议将密钥存储为regex对象以避免这种情况。

这并不能解决您的问题,但为什么要将模式存储为字符串而不是regex?没有真正的原因。我正在使用一种方法来存储散列,这样就更容易读取onpattern,&block hash[pattern]=block基本上就是我正在使用的方法,而且在“test.+?”上编写似乎更容易。这并不能解决您的问题,但为什么要将模式存储为字符串而不是正则表达式?没有真正的原因。我正在使用一种方法来存储散列,这样在模式上更容易读取,&block hash[pattern]=block基本上就是我正在使用的方法,而且在“test.+?”上写起来似乎更容易。谢谢。我不得不使用matchdata[1]而不是第一个,但这非常有效。哦,对了,我应该先测试一下。为了将来,我改变了答案。谢谢。我不得不使用matchdata[1]而不是第一个,但这非常有效。哦,对了,我应该先测试一下。为了将来,我改变了答案。