Mage
August 6, 2008, 6:05pm
1
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
Mage
August 6, 2008, 6:20pm
2
On Aug 6, 2008, at 10:03 AM, Mage wrote:
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
Mage
August 7, 2008, 4:22pm
3
Mage wrote:
Tim P. wrote:
with more time than me.
Won’t even work if any of the values contains a comma.
Mage
Why don’t you use YAML?
{ :qwe => “asd”}.to_yaml
=> “— \n:qwe: asd\n”
YAML.load(({ :qwe => “asd”}.to_yaml))
=> {:qwe=>“asd”}
It works for most of things.
Mage
August 8, 2008, 10:57pm
5
Maciej Tomaka wrote:
Why don’t you use YAML?
The input string isn’t generated by me, and I cannot change its format.
Mage
Mage
August 8, 2008, 11:41pm
6
On Wed, Aug 6, 2008 at 12:03 PM, Mage [email protected] wrote:
eval is easy and unsecure. Regexp is not very simple if you want handle
every special case (nested values etc).
You could try eval with a high SAFE level. Or write a quick parser
using TreeTop.
–
Avdi
Home: http://avdi.org
Developer Blog: Avdi Grimm, Code Cleric
Twitter: http://twitter.com/avdi
Journal: http://avdi.livejournal.com
Mage
August 9, 2008, 2:12am
7
Michael M. wrote:
map {|s|
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
Mage
August 9, 2008, 12:34am
8
Mage wrote:
Mage
You could do something like this:
#!/usr/bin/env ruby
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.
Mage
August 9, 2008, 4:04pm
9
Mage wrote:
Michael M. wrote:
map {|s|
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.