【问题标题】:parse only first level of json仅解析第一级 json
【发布时间】:2016-09-29 09:14:43
【问题描述】:

我有这种json文件:

{
"params": {
    "apiKey": "key",
    "sessionId": "123433890",
    "lang": "en",
    "timezone": "America/New_York",
    "query": "hi all",
    "latitude": "37.459157",
    "longitude": "-122.17926",
    "context": "[{"
     name ": "
     weather ","
     lifespan ": 4}]"
}

}

因为

,它不是有效的 json
"context": "[{"
     name ": "
     weather ","
     lifespan ": 4}]"

我无法使用 json_decode 对其进行解码。

所以我想知道是否可以只解码第一个键。所以结果可能看起来像

    array(1) {
  'parameters' =>
  array(8) {
    'apiKey' =>
    string(32) "key"
    'sessionId' =>
    string(10) "123433890"
    'lang' =>
    string(2) "en"
    'timezone' =>
    string(16) "America/New_York"
    'query' =>
    string(16) "hi all"
    'latitude' =>
    string(9) "37.459157"
    'longitude' =>
    string(10) "-122.17926"
    'context' =>
    string(16) "[{"name ": "weather ","lifespan ": 4}]"
  }
}

谢谢!

这也是有效的 json,但不能用 json_decode 解码。

    {
    "query": [
        "and for tomorrow"
    ],
    "contexts": "[{'name':'weather', 'lifespan' : 4}]",
    "location": {
        "latitude": 37.459157,
        "longitude": -122.17926
    },
    "timezone": "America/New_York",
    "lang": "en",
    "sessionId": "1234567890"
}

【问题讨论】:

  • 你自己做json吗?
  • @KinshukLahiri 查看更新
  • “这也是有效的 json” - 不,不是。它缺少一个开口{
  • PHP manual page on strings 中,它是“nowdoc”语法。

标签: php arrays json string


【解决方案1】:

您的 JSON 确实无效。它应该是这样的:

{
  "params": {
    "apiKey": "key",
    "sessionId": "123433890",
    "lang": "en",
    "timezone": "America/New_York",
    "query": "hi all",
    "latitude": "37.459157",
    "longitude": "-122.17926",
    "context": [{"name":"weather","lifespan": 4}]
  }
}

错误在于 context 键值被放在引号中,而它不应该被放在引号中,因为它不是字符串,而是嵌套对象。

如果您无法控制该文件并且无法修复它,那么您可以使用此代码,它会在您阅读后尝试为您修复它:

// Invalid JSON as read from your file:
$json = '{
  "params": {
    "apiKey": "key",
    "sessionId": "123433890",
    "lang": "en",
    "timezone": "America/New_York",
    "query": "hi all",
    "latitude": "37.459157",
    "longitude": "-122.17926",
    "context": "[{"
     name ": "
     weather ","
     lifespan ": 4}]"
  }
}';
// Fix malformed JSON
$json = preg_replace_callback('~"([\[{].*?[}\]])"~s', function ($match) {
    return preg_replace('~\s*"\s*~', "\"", $match[1]);
}, $json);
// Now you can do:
$arr = json_decode($json, true);

上面代码的结果是$arr会包含这个:

array (
  'params' => array (
    'apiKey' => 'key',
    'sessionId' => '123433890',
    'lang' => 'en',
    'timezone' => 'America/New_York',
    'query' => 'hi all',
    'latitude' => '37.459157',
    'longitude' => '-122.17926',
    'context' => array (
      array (
        'name' => 'weather',
        'lifespan' => 4,
      ),
    ),
  ),
)

查看它在eval.in 上运行。

注意context 属性也有结构化信息(一个数组)。

代码说明

首先搜索以下模式:

~"([\[{].*?[}\]])"~s

~ 只是正则表达式的分隔符。那么:

  • ":匹配双引号
  • ( ... ):定义了我们想要实际得到的部分:我们想要删除最外面的双引号,所以它们不在这些括号内。
  • [\[{]:匹配以下任一文字字符:[{
  • .*?:匹配任何字符,但不超过继续所需的字符(? 使其不贪婪,即懒惰)。
  • [}\]]:匹配以下任一文字字符:}]
  • s:这是一个修饰符,可以让 . 也匹配换行符

对于每场比赛,preg_replace_callback 将调用我们作为第二个参数传递的函数,并传递给它一个数组。数组的第一个元素将是完全匹配,而第二个元素将代表捕获的部分,即括号之间的部分(我们感兴趣的部分):

$match[1]

我们对其应用了一个新的正则表达式,它会删除双引号周围的所有空格,包括换行符。这样,像name 这样的键名将被紧紧地包裹在双引号中,应该是这样的:

~\s*"\s*~s

同样,~ 只是正则表达式的分隔符。

  • \s*:匹配任意数量的空格,包括换行符

如此修改的字符串必须返回到外部preg_replace_callback函数,该函数将使用它将它插入到最终结果字符串中。

解决真正的原因

当然,如果您确实可以控制文件,或者它是如何生成的,那么请解决这个问题的原因。

请注意,有效的 JSON 使用单引号来分隔字符串。它们必须是双引号。

【讨论】:

  • 太棒了!!这就是我需要的。如果你能解释一下这个 preg 是如何工作的,我将非常感谢你!
  • preg 应该是什么样子不仅要修复 "context": "[{"name ": "weather ", "lifespan ": 4}]" 还要修复 "contexts": "{"name ": "山姆"}"
  • 我添加了解释并调整了正则表达式以处理"{" .... "}"
【解决方案2】:

你提到的第二个无法解码的json。

解决办法如下:

$test = '{
"query": [
    "and for tomorrow"
],
"contexts": "[{\'name\':\'weather\', \'lifespan\' : 4}]",
"location": {
    "latitude": 37.459157,
    "longitude": -122.17926
},
"timezone": "America/New_York",
"lang": "en",
"sessionId": "1234567890"
}';

$j = json_decode($test);

print_r($j);

【讨论】:

    【解决方案3】:

    你是如何生成这个 json 的

    你的 json 生成可能有一些错误

    正确的json应该如下生成

    {
        "params": {
            "apiKey": "key",
            "sessionId": "123433890",
            "lang": "en",
            "timezone": "America/New_York",
            "query": "hi all",
            "latitude": "37.459157",
            "longitude": "-122.17926",
            "context": [{
             "name ":" ",
             "weather" :"a",
             "lifespan ": 4}]
        }
    
    }
    

    你可以检查相同的Here

    我认为您传递给上下文的值应该是您缺少的数组。

    【讨论】:

    • 谢谢,但如果它是有效的 json 则不会出现 :)) 认为它不是 json 对象而是字符串。
    猜你喜欢
    • 2021-02-18
    • 1970-01-01
    • 2014-08-12
    • 2014-08-24
    • 2019-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多