Convert named matches in MatchData to Hash
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
Alternatives:
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
make hash consistent when some of its keys are symbols and others are not
You could transform the keys of datas
to symbols:
Hash[ matchdatas.names.zip( matchdatas.captures ) ].transform_keys(&:to_sym)
Or to define your params hash with string keys:
params = { 'url' => 'http://myradiowebsite.com/thestation' }
How do you properly use 'match' to build a hash for every line in a file using ruby?
Things to consider:
IP_REGEX = '(?:\d{1,3}\.){3}\d{1,3}(?::\d+)?'
input = 'TCP OUTSIDE 4.2.2.2:443 INSIDE 10.17.21.44:63314, idle 0:00:44, bytes 11365, flags UIO'
input.scan(/(\w+)\s(#{ IP_REGEX })/)
# => [["OUTSIDE", "4.2.2.2:443"], ["INSIDE", "10.17.21.44:63314"]]
scan
looks for the pattern given and returns an array of all matching hits. Because I'm using captures, they're returned as sub-arrays.
If you want the result to be a hash you can do:
input.scan(/(\w+)\s(#{ IP_REGEX })/).to_h # => {"OUTSIDE"=>"4.2.2.2:443", "INSIDE"=>"10.17.21.44:63314"}
or, if you're on an older Ruby that doesn't support to_h
:
Hash[input.scan(/(\w+)\s(#{ IP_REGEX })/)] # => {"OUTSIDE"=>"4.2.2.2:443", "INSIDE"=>"10.17.21.44:63314"}
You could use a simpler scan
pattern and allow parallel assignment help you grab the IPs in order:
src, dst = input.scan(/#{ IP_REGEX }/)
Then grab the other two fields however you want and assign them all to your hash:
foo = {
src: src,
dst: dst,
...
}
But, really, I'd take advantage of named captures:
matches = input.match(/(?<src>#{ IP_REGEX }) \w+ (?<dst>#{ IP_REGEX }), idle (?<idle>\S+), bytes (?<bytes>\d+), flags (?<flags>\S+)/)
# => #<MatchData
# "4.2.2.2:443 INSIDE 10.17.21.44:63314, idle 0:00:44, bytes 11365, flags UIO"
# src:"4.2.2.2:443"
# dst:"10.17.21.44:63314"
# idle:"0:00:44"
# bytes:"11365"
# flags:"UIO">
matches['src'] # => "4.2.2.2:443"
matches['dst'] # => "10.17.21.44:63314"
matches['idle'] # => "0:00:44"
matches['bytes'] # => "11365"
matches['flags'] # => "UIO"
At this point matches
acts like a hash as far as allowing access to the individual elements.
If you don't like that it's a simple step to getting a real hash:
matches.names.zip(matches.captures).to_h
# => {"src"=>"4.2.2.2:443",
# "dst"=>"10.17.21.44:63314",
# "idle"=>"0:00:44",
# "bytes"=>"11365",
# "flags"=>"UIO"}
How can I get named parameters into a Hash?
def my_method(required_param, named_param_1: nil, named_param_2: nil)
named_params = method(__method__).parameters.each_with_object({}) do |p,h|
h[p[1]] = eval(p[1].to_s) if p[0] == :key
end
p named_params # {:named_param_1=>"hello", :named_param_2=>"world"}
# do something with the named params
end
my_method( 'foo', named_param_1: 'hello', named_param_2: 'world' )
Ruby Regex MatchData Object Captures Method Behaving Oddly
This is not a bug. It actually works properly. #captures
only returns captured contents which mean the contents that are matched for groups within round brackets ()
. If you modify your regex to /(?!gemspec)gem(.*)/
(notice the (.*)
part), reg.match("gem 'wirble', :group => :development").captures
will return [" 'wirble', :group => :development"]
.
How to do named capture in ruby
You should use match
with named captures, not scan
m = "555-333-7777".match(/(?<area>\d{3})-(?<city>\d{3})-(?<number>\d{4})/)
m # => #<MatchData "555-333-7777" area:"555" city:"333" number:"7777">
m[:area] # => "555"
m[:city] # => "333"
If you want an actual hash, you can use something like this:
m.names.zip(m.captures).to_h # => {"area"=>"555", "city"=>"333", "number"=>"7777"}
Or this (ruby 2.4 or later)
m.named_captures # => {"area"=>"555", "city"=>"333", "number"=>"7777"}
How can I use a regex match as a hash index in Ruby?
Try this
assessment.gsub(/#{farm.keys.join('|')}/, farm)
Ruby: Collect index from Array/String Matchdata
If you want to get each character's index as a hash, this would work:
b = %w(A B A A C C B D A D)
h = {}
b.each_with_index { |e, i|
h[e] ||= []
h[e] << i
}
h
#=> {"A"=>[0, 2, 3, 8], "B"=>[1, 6], "C"=>[4, 5], "D"=>[7, 9]}
Or as a "one-liner":
b.each_with_object({}).with_index { |(e, h), i| (h[e] ||= []) << i }
#=> {"A"=>[0, 2, 3, 8], "B"=>[1, 6], "C"=>[4, 5], "D"=>[7, 9]}
Related Topics
Trying to Get Svn2Git Working on Windows
Append Row to CSV File Ruby 1.9 CSV Lib
Get Available Diskspace in Ruby
How to Create a Folder (If Not Present) with Logger.New
How to Get The Pty.Spawn Child Exit Code
Prawnto Displaying Tables That Don't Break When New Page
How to Increment an Integer in Ruby
Ruby - No Pid Found in Tmp/Pids/Thin.Pid (Thin::Pidfilenotfound)
Run Selenium with Chrome Driver on Heroku: 'Cannot Find Chrome Binary'
Ruby on Rails Looks for CSS in Assets Instead of Public/Stylesheets
Sorting an Array of Arrays in Ruby
Ruby/Rails Collection to Collection
Open a File Case-Insensitively in Ruby Under Linux
Generate a 'Link_To' to the Controller Action 'Edit', Dynamically
Using Ruby 2.0 on Amazon Opsworks