7

I want to pre-parse a json an convert all numbers in the json (integers or float) to strings.

For example:

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

to this:

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

Update I have found the following but it does not work for floats:

$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"}]

Update 2 Fixed second float value. It had two points.

4
  • 1
    I have found this solution stackoverflow.com/questions/1777382/… but it does not work for floats. Commented May 7, 2015 at 18:20
  • You can set that comment as a update in your question Commented May 7, 2015 at 18:21
  • Does it need to be in PHP, or is another language solution acceptable? Commented May 7, 2015 at 18:37
  • Yes, It need to be in PHP Commented May 8, 2015 at 9:12

6 Answers 6

10

Use JSON_BIGINT_AS_STRING option:

json_decode($jsonString, false, 512, JSON_BIGINT_AS_STRING)

Sign up to request clarification or add additional context in comments.

Comments

2

Use this: It should work

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

5 Comments

It does not work. It returns: {"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662".837406e+09}
Sorry, it does not work but really returns this: {"integer""10000","big_integer""100000999499498485845848584584584","float1""1.121212","float2""8.226347662837406e+09"} with new new update2 in the question
Thank you @jibran-bhat. It works. Although now I have another problem related to this. I want to convert hte json to an object and then get the original json but the object has to use string for json numbers. More info: stackoverflow.com/questions/30123862/…
Never ever use regex for jsons. For example this could corrupt json containing strings with colons and numbers. And many other potential issues.
Why is this accepted? It fails on the scientific float: "float2" : 8.226347662837406e+09 and be aware it will also fail on lists "[1.2, 3.0]"
1

I like this is solution for big float:

$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));

This is code replace only float to string and you should use it before call json_decode()

JSON:

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

After decode:

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

Comments

1

Here is a regex which works on float numbers, and it works for attributes, but also arrays. It also works for negative floats.

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

If you also want to cover for scientific notations, this will work but this will also convert integers to strings

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

The inspiration was taken from this answer, i've adjusted the regex to be even able to use replace, and expanded it to work with arrays and negatives https://stackoverflow.com/a/35008486

Tested with string {"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}}

Issues

This will fail if there is whitespace in the json (which in production environment is never the case). If you have whitespace then you could just remove all whitespace with this (but if you have sentences anywhere in the json, this will merge it into a single long word)

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

Another issue with this approach is that the array matches are not safe if they are found within a string. These will be rare, but they still might happen.

This will fail {"last_name":"lastn,543.123ame"}

This will also fail {"last_name":"lastn[543.123ame"}

Unfortunately there is no straightforward way of getting around these limitations using only one regex pass. However, if you have a response that contains purely numbers, then this works like a charm!

Comments

0

If anyone was looking for regex to match also negative numbers, here it is:

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

Comments

0

Here is the most correct way to wrap such numbers in quotation marks, making them strings. This does not distort the original appearance of the json string and takes into account the scientific format. Github (composer)

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.