hash from string

M

Mage

Hello,

I have a string like: ' "gaz"=>"1", "viz"=>"1", "lift"=>"0",
"kamra"=>"1", "klima"=>"0" '
Is it possible to convert this easily to hash without calling eval or
writing regexp?

eval is easy and unsecure. Regexp is not very simple if you want handle
every special case (nested values etc).

Mage
 
T

Tim Pease

Hello,

I have a string like: ' "gaz"=>"1", "viz"=>"1", "lift"=>"0",
"kamra"=>"1", "klima"=>"0" '
Is it possible to convert this easily to hash without calling eval
or writing regexp?

eval is easy and unsecure. Regexp is not very simple if you want
handle every special case (nested values etc).

Mage


str = ' "gaz"=>"1", "viz"=>"1", "lift"=>"0", "kamra"=>"1",
"klima"=>"0" '

h = {}
str.split(',').each do |substr|
ary = substr.strip.split('=>')
h[ary.first.tr('"','')] = ary.last.tr('"','')
end


But that won't handle nested values -- that's left for someone else
with more time than me.

Blessings,
TwP
 
M

Mage

Tim said:
str = ' "gaz"=>"1", "viz"=>"1", "lift"=>"0", "kamra"=>"1", "klima"=>"0" '

h = {}
str.split(',').each do |substr|
ary = substr.strip.split('=>')
h[ary.first.tr('"','')] = ary.last.tr('"','')
end


But that won't handle nested values -- that's left for someone else
with more time than me.
Won't even work if any of the values contains a comma.

Mage
 
M

Maciej Tomaka

Mage said:
Won't even work if any of the values contains a comma.

Mage

Why don't you use YAML?
=> "--- \n:qwe: asd\n"
=> {:qwe=>"asd"}


It works for most of things.
 
M

Michael Morin

Mage said:
Hello,

I have a string like: ' "gaz"=>"1", "viz"=>"1", "lift"=>"0",
"kamra"=>"1", "klima"=>"0" '
Is it possible to convert this easily to hash without calling eval or
writing regexp?

eval is easy and unsecure. Regexp is not very simple if you want handle
every special case (nested values etc).

Mage

You could do something like this:

#!/usr/bin/env ruby
# UziMonkey <[email protected]>

str = %q{"gaz"=>"1", "viz"=>"1", "lift"=>"0", "kamra"=>"1","klima"=>"0"}

hash = Hash[*
str.
split(/, +/).
map {|s|
s.match( /"([^"]+)"=>"([^"]+)"/ )[1,2]
}.
flatten
]

puts hash.inspect

But the regex makes a lot of assumptions. If the format of the hash
changes at all (for example, quotes removed or changed to single
quotes), it will break. If not, it should work fine.

--
Michael Morin
Guide to Ruby
http://ruby.about.com/
Become an About.com Guide: beaguide.about.com
About.com is part of the New York Times Company
 
M

Mage

Michael said:
You could do something like this:

#!/usr/bin/env ruby
# UziMonkey <[email protected]>

str = %q{"gaz"=>"1", "viz"=>"1", "lift"=>"0", "kamra"=>"1","klima"=>"0"}

hash = Hash[*
str.
split(/, +/).
map {|s|
s.match( /"([^"]+)"=>"([^"]+)"/ )[1,2]
}.
flatten
]

puts hash.inspect

But the regex makes a lot of assumptions. If the format of the hash
changes at all (for example, quotes removed or changed to single
quotes), it will break. If not, it should work fine.

It won't work if any if the values has a comma, like str = ' "gaz" =>
"1", "lift" =>"white, small"'

split(/, +/) will break "white, small"

A much more complicated regexp should work. As far as I see I will stay
with eval.

Mage
 
M

Maciej Tomaka

Mage said:
It won't work if any if the values has a comma, like str = ' "gaz" =>
"1", "lift" =>"white, small"'

split(/, +/) will break "white, small"

A much more complicated regexp should work. As far as I see I will stay
with eval.

Mage

s = str.match(/^\s*\{\s*(.+)\}\s*$/).captures.first;
Hash[*s.scan(/\"([^"]*)\"\s*=>\s*\"([^"]*)\"/).flatten]

Lets assume that each hash is in form:
{ "something" => "someting elswe"[, *] }

Escaped " in strings are not supported here.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,774
Messages
2,569,598
Members
45,156
Latest member
KetoBurnSupplement
Top