将PHP中的json_decode整数和浮点数转换为字符串

7

我希望能够预处理一个JSON,并将其中所有数字(整数或浮点数)转换为字符串。

例如:

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

转换为:

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

更新 我找到了以下内容,但它不适用于浮点数:

$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 修正第二个浮点数值,它有两个小数点。


1
我找到了这个解决方案https://dev59.com/XkrSa4cB1Zd3GeqPWXGY?answertab=active#tab-top,但它不能处理浮点数。 - Jose Celano
你可以将该评论设置为问题的更新。 - SuperDJ
必须使用PHP吗?还是其他编程语言也可以接受? - Ignacio Vazquez-Abrams
是的,它需要用PHP编写。 - Jose Celano
6个回答

10
使用 JSON_BIGINT_AS_STRING 选项: json_decode($jsonString, false, 512, JSON_BIGINT_AS_STRING)

2
使用这个:它应该可以工作。
echo preg_replace('/\: *([0-9]+\.?[0-9e+\-]*)/', ':"\\1"', $jsonString);

它不起作用。它返回:{"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662".837406e+09} - Jose Celano
很抱歉,它不能工作,但真正返回的是:{"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662837406e+09"},问题中有新的更新2。 - Jose Celano
谢谢@jibran-bhat。它有效。虽然现在我有另一个与此相关的问题。我想将json转换为对象,然后获取原始json,但对象必须使用字符串来表示json数字。更多信息:http://stackoverflow.com/questions/30123862/encoding-and-decoding-floats-in-json-with-php-without-losing-precision - Jose Celano
永远不要使用正则表达式处理JSON。例如,这可能会破坏包含冒号和数字的字符串的JSON。还有许多其他潜在问题。 - Oleg
1
为什么这个被接受了?它在科学浮点数上失败了:"float2": 8.226347662837406e+09,而且请注意它也会在列表"[1.2, 3.0]"上失败。 - Grain

1

我喜欢这个用于大浮点数的解决方案:

$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',
          ),
      ),
    )

1
这是一个适用于浮点数的正则表达式,它适用于属性以及数组。它也适用于负数浮点数。
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"}

不幸的是,只使用一个正则表达式无法轻松解决这些限制。但是,如果您得到的响应仅包含数字,则这种方法可以运作得很好!


0

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

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

0

这里是将这些数字用引号括起来,转换成字符串的最正确方法。这不会扭曲JSON字符串的原始外观,并考虑了科学格式。Github (composer)

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接