0

好吧,我正在尝试从 Google Suggest 工具中检索一些信息。

问题是,请求后返回的 json 似乎无法解码(使用json_decode)+ JSONLint 将其视为“无效”。

怎么了?

{
    e: "GooDUs7lFIeXO63LgBA",
    c: 0,
    u: "https://www.google.com/s?gs_rn\x3d24\x26gs_ri\x3dpsy-ab\x26tok\x3dt8ORbtI13MEFLoCQjPSv6w\x26cp\x3d2\x26gs_id\x3d3i\x26xhr\x3dt\x26q\x3dtemplate\x26es_nrs\x3dtrue\x26pf\x3dp\x26safe\x3doff\x26sclient\x3dpsy-ab\x26oq\x3d\x26gs_l\x3d\x26pbx\x3d1\x26bav\x3don.2,or.r_cp.r_qf.\x26bvm\x3dbv.50500085,d.bGE\x26fp\x3dc513cf9c63a02102\x26biw\x3d1304\x26bih\x3d437\x26tch\x3d1\x26ech\x3d20\x26psi\x3dFYkDUs-xCsrT4QTD9YGwDw.1375963413783.1",
    p: true,
    d: "[\x22template\x22,[[\x22template\\u003cb\\u003es\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e monster\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003e c++\\u003c\\/b\\u003e\x22,0],[\x22template\\u003cb\\u003es for pages\\u003c\\/b\\u003e\x22,0]],{\x22t\x22:{\x22bpc\x22:false,\x22tlw\x22:false},\x22q\x22:\x22YjrI_EdhVrEkZrkqZwaGIJ_Ih4c\x22,\x22j\x22:\x223i\x22}]"
}

这就是 JSONLint 给出的错误:

Parse error on line 1:
{    e: "GooDUs7lFIeXO63L
-----^
Expecting 'STRING', '}'

PS即使在编辑它之后"e":,它仍然会给出关于价值的错误,u并声称它期待一个STRINGNUMBER等等......:S

4

3 回答 3

1

问题中给出的代码不是有效的 JSON。

为了成为有效的 JSON,需要在引号中命名字段。e变量名称或任何其他名称周围没有引号。

这就是 JSON 解码器所抱怨的:它期望看到"e",而不是e.

另外,JSON 不接受\x转义格式(十六进制字符引用);它只能使用\u格式(十进制的unicode字符引用)。您提供的代码包括两种格式的转义字符。

问题是,您使用的是官方的 Google API 吗?因为它们通常非常擅长提供有效的 JSON。这不是有效的 JSON,因此可能是您没有使用正确的 API。另一个线索是变量名不是很有意义。官方 API 通常会给出更有意义的变量名。如果它是正确的 API,您应该尝试向 Google 提出请求以修复它;损坏的 JSON 不好,但对他们来说修复起来应该很简单。

假设您无法让他们修复它并且我们找不到提供有效数据的替代 API 位置,我们如何处理我们所拥有的?

虽然此代码可能不是有效的 JSON,但它作为 Javascript 对象是有效的(JSON 规则比普通 Javascript 的规则更严格)。因此eval(),如果您对此足够信任,它可以使用 Javascript 解释器在 Javascript 解释器中运行。

唯一的其他替代方法是在解析字符串之前修复字符串,以便引用变量名。这有点痛苦,但如果输出是一致的,那将是可行的。但如果它发生变化,你就会遇到问题(同样,如果它是一个非官方的 API,这可能随时发生而不会发出警告)。

于 2013-08-08T13:18:20.697 回答
0

好的,这就是我最终做的事情(一点也不优雅,但它有效):

    $content = preg_replace_callback(
      "(\\\\x([0-9a-f]{2}))i",
      function($a) {return chr(hexdec($a[1]));},
      $content
    );
    $content = str_replace("e:","\"e\":",$content);
    $content = str_replace("c:","\"c\":",$content);
    $content = str_replace("u:","\"u\":",$content);
    $content = str_replace("p:","\"p\":",$content);
    $content = str_replace("d:","\"d\":",$content);
    $content = str_replace("\"[","[",$content);
    $content = str_replace("]\"","]",$content);

    $content = json_decode($content);
于 2013-08-08T13:26:36.297 回答
0

问题出backslashes在字符串中(用于转义字符)

在 PHP 5.4 中,您可以使用JSON_UNESCAPED_SLASHES

echo json_encode(JSON_STRING, JSON_UNESCAPED_SLASHES);

否则,您可以进行更换-

str_replace('\\/', '/', json_encode(JSON_STRING));

因为\/是一种有效的表示方式/

于 2013-08-08T12:27:26.827 回答