【问题标题】:PHP json_decode integers and floats to stringPHP json_decode 整数和浮点数到字符串
【发布时间】:2015-07-18 11:35:03
【问题描述】:

我想预先解析一个 json 并将 json 中的所有数字(整数或浮点数)转换为字符串。

例如:

{
 "integer": 10000,
 "big_integer": 100000999499498485845848584584584,
 "float1" : 1.121212,
 "float2" : 8.226347662837406e+09
}

到这里:

{
 "integer": "10000",
 "big_integer": "100000999499498485845848584584584",
 "float1" : "1.121212",
 "float2" : "8226347662.837406"
}

更新 我找到了following,但它不适用于浮动:

$jsonString = '[{"name":"john","id":5932725006},{"name":"max","id":4953467146}]';

echo preg_replace('/("\w+"):(\d+)/', '\\1:"\\2"', $jsonString);
//prints [{"name":"john","id":"5932725006"},{"name":"max","id":"4953467146"}]

更新 2 修复了第二个浮点值。它有两点。

【问题讨论】:

  • 我找到了这个解决方案stackoverflow.com/questions/1777382/…,但它不适用于浮动。
  • 您可以将该评论设置为问题中的更新
  • 是否需要使用 PHP,还是可以接受其他语言解决方案?
  • 是的,它需要在 PHP 中

标签: php json numbers


【解决方案1】:

这是一个适用于浮点数的正则表达式,它适用于属性,也适用于数组。它也适用于 negative 浮点数。

preg_replace('/((?<=":)|(?<=\[)|(?<=,))(?<!")(-?\d+\.\d+)(?!")/', '"$2"', $json)

如果您还想涵盖科学记数法,这将有效,但也可以将整数转换为字符串

preg_replace('/((?<=":)|(?<=\[)|(?<=,))(?<!")(-?[\d\.]+((e|E)(\+|-)\d+)?)(?!")/', '"$2"', $json)

灵感来自这个答案,我调整了正则表达式甚至可以使用替换,并将其扩展为使用数组和负数https://stackoverflow.com/a/35008486

用字符串测试 {"array":[[0.00004639,683724.2687321],[0.00004658,190091.61007863,190091.61007863]],"and_finally":{"negative_float":-1.123,"negative_int":-1,"first_name":"sa123mp5e-19le","last_name":"la5.1e+5stn543.123,ame","integer":"100","another_float":"1555.20","int":100,"float":1555.20,"floatAsString":"1555.20","date":"2015-01-01 15:23:51","somefloat":[14,23],"somefloat2":[5e-7,23.33],"scientific_negative_float":5.2e-7,"scientific_positive_float":5E+19}}

问题

如果 json 中有空格(在生产环境中绝不会出现这种情况),这将失败。如果你有空格,那么你可以用这个删除所有空格(但如果你在 json 中的任何地方都有句子,这会将它合并成一个长单词)

preg_replace('/\s/', '', $json)

这种方法的另一个问题是,如果在字符串中找到数组匹配项,则它们是不安全的。这些情况很少见,但仍有可能发生。

这将失败{"last_name":"lastn,543.123ame"}

这也会失败 {"last_name":"lastn[543.123ame"}

不幸的是,仅使用一个正则表达式传递没有直接的方法来解决这些限制。但是,如果您有一个包含纯数字的响应,那么这就像一个魅力!

【讨论】:

    【解决方案2】:

    这是将这些数字用引号括起来的最正确方法,使它们成为字符串。这不会扭曲 json 字符串的原始外观并考虑到科学格式。 Github (composer)

    $regexp = '/"(\s*)\:(\s*)(\-?\d+([eE][\+|\-]?\d+|\.\d+)+)(\s*[,(\s*)|\}])/';
    $json_string = preg_replace($regexp, "$1:$2\"$3\"$5", $json);
    

    【讨论】:

      【解决方案3】:

      如果有人在寻找正则表达式来匹配负数,这里是:

      echo preg_replace('/\: *([0-9]+\.?[0-9e+\-]*|-[0-9]+\.?[0-9e+\-]*)/', ':"\\1"', $jsonString);
      

      【讨论】:

        【解决方案4】:

        我喜欢这是大浮动的解决方案:

        $json = '{"data":[[0.00004639,683724.2687321],[0.00004658,190091.61007863]]}';
        
        $json = preg_replace('/([0-9]+)\.([0-9]+)/', '"$1.$2"', $json);
        
        print_r(json_decode($json, true));
        

        这是代码替换只浮动到字符串,你应该在调用 json_decode() 之前使用它

        JSON:

        {"data":[[0.00004639,683724.2687321],[0.00004658,190091.61007863]]}
        

        解码后:

         array (
              'data' => array (
                  0 => array (
                    0 => '0.00004639',
                    1 => '683724.2687321',
                  ),
                  1 => array (
                    0 => '0.00004658',
                    1 => '190091.61007863',
                  ),
              ),
            )
        

        【讨论】:

          【解决方案5】:

          使用JSON_BIGINT_AS_STRING 选项:

          json_decode($jsonString, false, 512, JSON_BIGINT_AS_STRING)

          【讨论】:

            【解决方案6】:

            使用这个:它应该可以工作

            echo preg_replace('/\: *([0-9]+\.?[0-9e+\-]*)/', ':"\\1"', $jsonString);
            

            【讨论】:

            • 它不起作用。它返回:{"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662".837406e+09}
            • 抱歉,它不起作用但确实返回了这个:{"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662837406e+09"} 问题中有新的更新2
            • 谢谢@jibran-bhat。有用。虽然现在我有另一个与此相关的问题。我想将 hte json 转换为一个对象,然后获取原始 json,但该对象必须使用字符串作为 json 数字。更多信息:stackoverflow.com/questions/30123862/…
            • 永远不要对 json 使用正则表达式。例如,这可能会损坏包含带有冒号和数字的字符串的 json。以及许多其他潜在问题。
            • 为什么会被接受?它在科学浮点数上失败:“float2”:8.226347662837406e+09 并注意它也会在列表“[1.2, 3.0]”上失败
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-02-27
            • 1970-01-01
            • 1970-01-01
            • 2022-10-16
            • 2016-05-02
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多