将JSON字符串转换为哈希表

8

我能提供Ruby on Rails的JSON问题解答。

我有一个看起来比较奇怪的错误。我从外部API获取以下JSON字符串:

test = "[{'domain': 'abc.com'}, {'domain': 'def.com'}, {'domain': 'ghi.com'}]"

现在,我想使用以下方式将这个字符串转换为哈希表:
hash = JSON.parse test

问题是它报错了:“”
JSON::ParserError: 419: unexpected token at '{'domain': 'abc.com'}, {'domain': 'def.com'}, {'domain': 'ghi.com'}]'

现在仅仅用"替换'是危险的,因为如果任何字符串包含'或",就会出现问题。是否有解决方案?


你可以使用 JSON.parse test.gsub("'", '"')。这将删除所有单引号,然后解析该字符串。 - Santhosh
我从外部API获取了这个JSON,所以你的解决方案可能是最好的。谢谢! - JayC
然而,如果JSON值中存在 '",将所有的 ' 替换为 " 可能会破坏JSON,这可能会导致问题... 有人有解决方案吗? - JayC
4个回答

12

这很可能是因为这不是有效的JSON格式。请将单引号改成双引号,就像这样:

test = '[{"domain": "abc.com"}, {"domain": "def.com"}, {"domain": "ghi.com"}]'

可以在这里找到解释,您可以在这里验证您的JSON。


问题在于我从外部API获取的数据是这样的。有没有一种安全的方法将其“转换”为真正的JSON?仅仅替换'是很危险的。 - JayC
你关于“仅仅替换'”是危险的说法是正确的。不幸的是,没有一个很好的方法来解决这个问题。我强烈建议给API提供者发送电子邮件(或者如果他们有某种系统设置,则提交问题),并告诉他们他们的API与所有严格的JSON解析器不兼容(这可能包括Ruby、Java、Python、PHP、.NET等几乎所有语言,除了在JavaScript运行时中调用eval,这是任何明智的开发人员都不想冒的风险)。 - Jordan Running
ŠłĹšöĘ JSON.parse test.gsub("{'", '{"').gsub("':'", '":"').gsub("' : '", '":"').gsub("' :'", '":"').gsub("': '", '":"').gsub("'}", '"}').gsub("':", '":').gsub(", '", ',"').gsub(",'", ',"').gsub("' ,", '",').gsub("',", '",').gsub("u'", '"').gsub("']", '"]').gsub("['", '["') Ŕžúňć│ń║ćň«â´╝łńŞĹÚÖőšÜäń┐«ňĄŹŠľ╣ň╝Ćň║öŔ»ąšŤŞňŻôň«ëňůĘ´╝ëŃÇé - JayC
1
那很丑,而且说实话不应该用作生产解决方案。我同意Jordan的观点:与提供API的人交谈。他们有责任创建一些用户可以使用的东西(目前它并没有做到)。这是商业API吗? - MyCah

6
您遇到错误是因为您的字符串不是有效的JSON格式。在JSON中,所有属性名称都必须使用双引号括起来,字符串值也必须使用双引号括起来。单引号从未被认为是有效的。
test = '[{"domain": "abc.com"}, {"domain": "def.com"}, {"domain": "ghi.com"}]'
JSON.parse(test)
# => [ { "domain" => "abc.com" },
#      { "domain" => "def.com" },
#      { "domain" => "ghi.com" } ]

5

如果你想在Rails 4或以上版本中使用符号键而不是字符串键,可以使用deep_symbolize_keys方法。

hash = JSON.parse(test).deep_symbolize_keys

此外,真正的问题是无效的 JSON,就像 MyCah 所提到的。


0
使用这段代码。你缺少了 ActiveSupport::JSON。
  ActiveSupport::JSON.decode json_string

1
尝试过:hash = ActiveSupport::JSON.decode test。出现了相同的错误,抱歉。 - JayC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接