4

我像这样从苹果那里得到了 JSON

{
    "original-purchase-date-pst" = "2012-06-28 02:46:02 America/Los_Angeles";
    "original-transaction-id" = "1000000051960431";
    "bvrs" = "1.0";
    "transaction-id" = "1000000051960431";
    "quantity" = "1";
    "original-purchase-date-ms" = "1340876762450";
    "product-id" = "com.x";
    "item-id" = "523404215";
    "bid" = "com.x";
    "purchase-date-ms" = "1340876762450";
    "purchase-date" = "2012-06-28 09:46:02 Etc/GMT";
    "purchase-date-pst" = "2012-06-28 02:46:02 America/Los_Angeles";
    "original-purchase-date" = "2012-06-28 09:46:02 Etc/GMT";
}

这不是我们所知道的JSON 。在 JSON 中,它明确定义为

每个名称后跟 :(冒号),名称/值对用 ,(逗号)分隔。

我什至如何在 python 的 json (或 simplejson )模块中解析它?

json仅支持separatorsin json.dumps()、 not injson.loads()和 in simplejson/decoder.py, the具有and的def JSONObject()硬编码分隔符。:,

我能做些什么?写我自己的解析器?

4

3 回答 3

5

那确实比较乱。一个快速的解决方法是用正则表达式替换有问题的分隔符:

line = re.compile(r'("[^"]*")\s*=\s*("[^"]*");')
result = line.sub(r'\1: \2,', result)

您还需要删除最后一个逗号:

trailingcomma = re.compile(r',(\s*})')
result = trailingcomma.sub(r'\1', result)

通过这些操作,示例加载为 json:

>>> import json, re
>>> line = re.compile('("[^"]*")\s*=\s*("[^"]*");')
>>> result = '''\
... {
...     "original-purchase-date-pst" = "2012-06-28 02:46:02 America/Los_Angeles";
...     "original-transaction-id" = "1000000051960431";
...     "bvrs" = "1.0";
...     "transaction-id" = "1000000051960431";
...     "quantity" = "1";
...     "original-purchase-date-ms" = "1340876762450";
...     "product-id" = "com.x";
...     "item-id" = "523404215";
...     "bid" = "com.x";
...     "purchase-date-ms" = "1340876762450";
...     "purchase-date" = "2012-06-28 09:46:02 Etc/GMT";
...     "purchase-date-pst" = "2012-06-28 02:46:02 America/Los_Angeles";
...     "original-purchase-date" = "2012-06-28 09:46:02 Etc/GMT";
... }
... '''
>>> line = re.compile(r'("[^"]*")\s*=\s*("[^"]*");')
>>> trailingcomma = re.compile(r',(\s*})')
>>> corrected = trailingcomma.sub(r'\1', line.sub(r'\1: \2,', result))
>>> json.loads(corrected)
{u'product-id': u'com.x', u'purchase-date-pst': u'2012-06-28 02:46:02 America/Los_Angeles', u'transaction-id': u'1000000051960431', u'original-purchase-date-pst': u'2012-06-28 02:46:02 America/Los_Angeles', u'bid': u'com.x', u'purchase-date-ms': u'1340876762450', u'original-transaction-id': u'1000000051960431', u'bvrs': u'1.0', u'original-purchase-date-ms': u'1340876762450', u'purchase-date': u'2012-06-28 09:46:02 Etc/GMT', u'original-purchase-date': u'2012-06-28 09:46:02 Etc/GMT', u'item-id': u'523404215', u'quantity': u'1'}

它也应该处理嵌套映射。这确实假设值本身没有转义"引号。如果有的话,无论如何你都需要一个解析器。

于 2012-06-28T10:38:38.400 回答
3

如果将以下内容添加到 iTunes 的 HTTP 请求标头中

{'Content-Type' : 'application/json'}

它将返回一个真正的 JSON 格式的响应,该响应将与 json.loads 一起使用

于 2013-08-12T21:36:50.827 回答
1

我让这个辅助函数工作了,目前它似乎工作得很好。我正在使用它将传入(未经验证的)收据转换为 JSON 并提取交易 ID。验证后,我比较了 2 个交易 ID 以确保它们匹配:

    function PropertyArrayStringToArray($data)
    {
        $data = str_replace(PHP_EOL, '', $data); 
        $data = preg_replace('/\t/', '', $data);  
        $data = str_replace('" = "'  ,'":"',$data);
        $data = str_replace('"="'    ,'":"',$data);
        $data = str_replace('";'     ,'",',$data);
        $data = str_replace(',}'     ,'}',$data);
        return json_decode($data,true);
    }

随意使用它(风险自负)并改进它。

于 2015-04-09T12:56:42.507 回答