Reputation: 1878
I have a JSON fragment I need to parse:
fragment = "\"product name\":\"12 oz. Coke\", \"more keys\":\"another value\""
I want to get the value out of any key given that key's name.
I have tried:
fragment.match/\"product name\"\:\"(.+)\"/
but I get unterminated string meets end of file.
Can you help me grab the string 12 oz. Coke
?
Upvotes: 0
Views: 2086
Reputation: 84373
You can use JSON#parse and a little interpolation to turn your string into a normal Ruby Hash object. A Hash will expose all sorts of useful utility methods to get at your data. For example:
# use interpolation to convert to valid JSON, then parse to Hash
fragment = "\"product name\":\"12 oz. Coke\", \"more keys\":\"another value\""
hash = JSON.parse '{%s}' % fragment
#=> {"product name"=>"12 oz. Coke", "more keys"=>"another value"}
# manipulate your new Hash object
hash['product name']
#=> "12 oz. Coke"
hash.keys
#=> ["product name", "more keys"]
hash.values
#=> ["12 oz. Coke", "another value"]
Upvotes: 1
Reputation: 156444
Just to demonstrate how you might do this using the builtin JSON parser (if that were an option):
require 'json'
fragment = '"product name":"12 oz. Coke", "more keys":"another value"'
hash = JSON.parse('{' + fragment + '}')
hash['product name'] # => "12 oz. Coke"
Upvotes: 0
Reputation: 7725
You can capture the 'value' part in the 'key-value' pattern:
str = %q("product name":"12 oz. Coke", "more keys":"another value")
str.scan /".+?":"(.+?)"/
=> [["12 oz. Coke"], ["another value"]]
http://rubular.com/r/Add4Ftf4cJ
Upvotes: 1
Reputation: 13911
You do not need to escape quote-signs in regexp, also, add a ?-mark to make the search lazy. This works for me:
fragment = "\"product name\":\"12 oz. Coke\", \"more keys\":\"another value\""
p fragment[/"more keys":"(.+?)"/, 1] # => "another value"
p fragment[/"product name":"(.+?)"/, 1] # => "12 oz. Coke"
Edit:
An alternative would be to put the data into a hash:
p Hash[fragment.gsub('"','').split(',').map{|x|x.strip.split(':')}]
# => {"product name"=>"12 oz. Coke", "more keys"=>"another value"}
Upvotes: 1
Reputation: 60224
I'm not sure about all of the formats of JSON, but one method would be to
Match the key name -- probably best to set case insensitive
Match the separator characters
Match anything that is not a termination character into a capturing group:
/product name[\\": ]+([^\\]+)/i
Another way, using your method, would be to make the capturing group lazy. And also remember that in Ruby, you need to use \\ rather than \. So:
/"\\"product name\\":\\"(.+?)\\/i
Depending on your data, you might also need to turn on "dot matches newline"
/"\\"product name\\":\\"(.+?)\\/mi
Upvotes: 0