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

时间:2011-01-17 23:31:36

标签: ruby regex block

我有一个哈希,密钥为regex,值为block。如下所示:

{ 'test (.+?)' => { puts $1 } }
显然,

不是完全,因为块被存储为Proc,但这就是想法。

之后我接受了一次正则表达式匹配,看起来很像这个

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

我的想法是将块存储在哈希中,以便我将来更容易扩展,但现在regex捕获不会传递给块。有没有办法干净利落地支持我放在regex中的任意数量的捕获(如,某些regex模式可能有1次捕获,其他可能有3次)?

2 个答案:

答案 0 :(得分:3)

如果您将匹配数据传递到过程中该怎么办?

hash.each do |pattern, action|
  if pattern.match(string)
    action.call($~)
  end
end

你的哈希会变成:

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

答案 1 :(得分:1)

我会使用Hash.find遍历哈希元素,将它们一次一个地传递给一个块。返回true的那个获胜:

这样的事情:

hash = {/foo/ => lambda { 'foo' }, /bar/ => lambda { 'bar' } }
str = 'foo'
puts hash.find{ |n,v| str =~ n }.to_a.last.call

显然我正在使用lambda,但它足够接近。并且,如果没有匹配,则需要处理nil值。举个例子我把to_a.last.call链接起来,但在现实生活中,你想要对零做出反应,否则Ruby会生气。

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