本文介绍了将MatchData中的已命名匹配转换为哈希的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的正则表达式,但是我想使用命名的正则表达式使它更整洁,然后遍历结果.

I have a rather simple regexp, but I wanted to use named regular expressions to make it cleaner and then iterate over results.

测试字符串:

testing_string = "111x222b333"

我的正则表达式:

regexp = %r{
                (?<width> [0-9]{3} ) {0}
                (?<height> [0-9]{3} ) {0}
                (?<depth> [0-9]+ ) {0}

                \g<width>x\g<height>b\g<depth>
            }x
dimensions = regexp.match(testing_string)

这项工作很吸引人,但问题出在这里:

This work like a charm, but heres where the problem comes:

dimensions.each { |k, v| dimensions[k] = my_operation(v) }

# ERROR !

 undefined method `each' for #<MatchData "111x222b333" width:"111" height:"222" depth:"333">.

MatchData对象中没有.each方法,我真的不想猴子修补它.

There is no .each method in MatchData object, and I really don't want to monkey patch it.

如何解决此问题?

我并没有我想的那么清楚:关键是要保留名称和类似哈希的结构.

I wasn't as clear as I thought: the point is to keep names and hash-like structure.

推荐答案

如果您需要完整的哈希:

If you need a full Hash:

captures = Hash[ dimensions.names.zip( dimensions.captures ) ]
p captures
#=> {"width"=>"111", "height"=>"222", "depth"=>"333"}

如果您只想遍历名称/值对:

If you just want to iterate over the name/value pairs:

dimensions.names.each do |name|
  value = dimensions[name]
  puts "%6s -> %s" % [ name, value ]
end
#=>  width -> 111
#=> height -> 222
#=>  depth -> 333

替代品:

dimensions.names.zip( dimensions.captures ).each do |name,value|
  # ...
end

[ dimensions.names, dimensions.captures ].transpose.each do |name,value|
  # ...
end

dimensions.names.each.with_index do |name,i|
  value = dimensions.captures[i]
  # ...
end

这篇关于将MatchData中的已命名匹配转换为哈希的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-22 10:03