【问题标题】:php json_decode fails without quotes on keyphp json_decode 失败,键上没有引号
【发布时间】:2011-08-04 12:44:22
【问题描述】:

我有这样表示的 json 数据

{key:"value"}

(键周围没有引号...)

我想把它翻译成一个关联数组。

PHP 的 json_decode 返回 null

如何在键周围添加引号? 谢谢...

【问题讨论】:

  • 没有内置函数,但就像说亚当看起来从你得到你的 JSON 的地方正确发送它
  • 不幸的是,JSON 遇到这种情况并不少见。谷歌做到了...google.com/ig/calculator?hl=en&q=1%20USD=?CAD
  • 您的链接返回 404 @Laizer 并且此处列出的 JSON 无效

标签: php json


【解决方案1】:

您可以在源处修复 JSON 以使其返回有效的 JSON 结构,也可以手动在键周围添加引号。

This answer 对一个类似的问题有一个如何做到这一点的示例:

function my_json_decode($s) {
    $s = str_replace(
        array('"',  "'"),
        array('\"', '"'),
        $s
    );
    $s = preg_replace('/(\w+):/i', '"\1":', $s);
    return json_decode(sprintf('{%s}', $s));
}

【讨论】:

  • 感谢您的解决方案。但我不得不删除 sprintf('{%s}', $s) 并且只使用 $s 作为 json_decode 函数的参数。
  • 优秀的解决方案。我不确定为什么 Manjula 还没有接受这个作为正确答案...... 2 年后......
  • 不是一个有效的解决方案!尝试将键或“值”设置为 url 或其中带有冒号的内容。这将失败。例如 {key:"va:lue"}
  • preg_replace('/(\n[\s||\t]*)(\w+):[\s||\t]/i', '$1"$2":', $json);
  • 只是没有在我的 json 中添加任何引用..为什么这甚至投票这么多
【解决方案2】:

如果您无法在源代码中将其转换为有效的 JSON,那么您可以使用 PEAR 中的 Services_JSON 对其进行解析,因为在密钥周围添加引号是一个非常容易出错的过程。

Services_JSON 将正确解析无效的密钥字符串。

例子:

$json = new Services_JSON();
var_dump($json->decode('{key:"value"}'));

输出:

object(stdClass)#2 (1) {
  ["key"]=>
  string(5) "value"
}

【讨论】:

  • 谢谢,正是我一直在寻找的东西,并且这些年来仍然可以在现代版本的 PHP 中工作(在 7.3 上测试)-顺便说一句,如果你想要数组而不是对象,那么将其构造为 $json_decoder = new Services_JSON(SERVICES_JSON_IN_ARR | SERVICES_JSON_LOOSE_TYPE);
【解决方案3】:

为避免将双引号插入不应插入的位置,您应该在此操作中跳过那些带引号的字符串。

例如,如果你在一个字符串中有这个 JavaScript 对象字面量:

{
   dt:"2016-10-22T09:13:20",
   "x:y":false
}

...那么必须注意不要将22T09: 更改为"22T09":。此外,已引用的密钥 "x:y" 应保持不变。

你可以使用这个正则表达式来实现:

preg_replace('/("(.*?)"|(\w+))(\s*:\s*(".*?"|.))/s', '"$2$3"$4', $text);

其他问题

JavaScript 对象字面量允许带有左填充零的数字常量,例如 001,和/或带有一元 + 符号,这在 JSON 中是不允许的。要删除这些违规字符,您可以使用此扩展版本:

preg_replace('/("(.*?)"|(\w+))(\s*:\s*)\+?(0+(?=\d))?(".*?"|.)/s', '"$2$3"$4$6', $text);

【讨论】:

    【解决方案4】:

    请不要使用正则表达式来执行此操作!根据定义,JSON 语法不能以这种方式正确解析。您将向未来的大量错误敞开大门。

    我建议使用 YAML 解析器,因为 YAML 是 JSON 的超集,同时允许使用不带引号的文字。

    Symfony YAML component 效果很好。

    与原生实现的json_decode 相比,会有性能损失。

    【讨论】:

      【解决方案5】:

      不要使用正则表达式。

      在这种情况下完全不建议使用 REGEX,不要使用它来解析此类数据。如果您有一个简单的目标并想避免使用稳定的PEAR package,那么您可以尝试JSON-php 库(但不再维护)。

      1) 从here 获取JSON.phps 文件并重命名为.php 并将构造函数名称替换为__construct

      2) 用法:

      $content = '{myKey:"valueeeee"}';
      
      include(__DIR__.'/JSON.php'); 
      $this->json = new Services_JSON( SERVICES_JSON_LOOSE_TYPE );  // to return objects instead of Associative array, remove the argument
      var_dump( $this->json->decode($content)  );
      

      【讨论】:

      • 如何将这个添加到 laravel 控制器?
      • 这工作完美,并将损坏的 JSON 解码为正确的数组。然后我可以调用 json_encode 来正确编码它。谢谢!
      【解决方案6】:
      $results = \Symfony\Component\Yaml\Yaml::parse("{a: d, b: 'c', e: [a, 3]}");
      

      您可能只能使用该库而不必使用整个 Symfony 包:https://packagist.org/packages/symfony/yaml

      【讨论】:

        【解决方案7】:

        根据documentation(参见示例#3 - '使用 json_decode 的常见错误'),键必须用双引号括起来。

        您从哪里获取 JSON 数据?

        【讨论】:

        • .. 因此你没有“json数据”——至少没有有效的。
        • 这本来更适合作为评论,因为它不会尝试回答“如何添加引号...”的问题
        【解决方案8】:

        这对我有用,使用正则表达式替换 '/\s(\w+)\s/i'

        $json =  file_get_contents("php://input"); // or whatever json data
        $json = preg_replace('/\s(\w+)\s/i', '"$1"', $json);
        $json = json_decode($json, true);
        

        【讨论】:

        • 这将在值内添加双引号,而如果键周围没有空格,它将丢失键:{s:"this is my string", flag: false , n: 9 } 将变为{s:"this"is"my string", flag:"false", n:"9"}
        • 只需在正则表达式中添加:,它实际上应该被选为一个好的答案
        猜你喜欢
        • 2017-01-07
        • 1970-01-01
        • 2011-01-20
        • 1970-01-01
        • 1970-01-01
        • 2012-12-02
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多