5

I have some regular expressions in my JSON, which doesn't seem to be a problem when I test my JSON on an online JSON validator. However, when I take that JSON string and try to json_decode() in PHP, I get a JSON_ERROR_SYNTAX.

Any ideas why? And how do I solve this?

Sample code:

<?php

$json = <<<EOD
{
  "regex": [
    "Hello\s+World"
  ]
}
EOD;

json_decode($json);

switch (json_last_error()) {
    case JSON_ERROR_NONE:
        echo ' - No errors';
    break;
    case JSON_ERROR_DEPTH:
        echo ' - Maximum stack depth exceeded';
    break;
    case JSON_ERROR_STATE_MISMATCH:
        echo ' - Underflow or the modes mismatch';
    break;
    case JSON_ERROR_CTRL_CHAR:
        echo ' - Unexpected control character found';
    break;
    case JSON_ERROR_SYNTAX:
        echo ' - Syntax error, malformed JSON';
    break;
    case JSON_ERROR_UTF8:
        echo ' - Malformed UTF-8 characters, possibly incorrectly encoded';
    break;
    default:
        echo ' - Unknown error';
    break;
}

The problem is in the \s. Changing it to \\s doesn't help.

2
  • Which online JSON validator validates the one in this question? Commented Jan 23, 2019 at 8:20
  • Take a look at this package. You can easily convert an array to a JSON string using it. Commented Jan 25, 2019 at 15:36

3 Answers 3

7

When you write "\s" in PHP the literal string is \s because \s is not a valid escape sequence.

When you write "\\s" in PHP the literal string is \s because \\ is a valid escape sequence.

JSON, on the other hand will throw an error for invalid escape sequences, which is your issue.

The solution: Don't write JSON by hand.

$json = json_encode(['regex'=> ['Hello\s+World']]);

Output: {"regex":["Hello\\s+World"]} [note: literal string, valid JSON]

The Bad Solution That's More Trouble than it's Worth and Will Probably Cause Problems Down the Line: "Hello\\\s+World" welcome to escaping hell.

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

2 Comments

When I json_decode as JSON array, I expect a PHP array in return. I'm getting a string. Any ideas what's going on?
Your array probably has been encoded several times. Show your starting JSON.
3
+50

Your string "Hello\s+World" must be escaped like "Hello\\\s+World". The first escape \ is for escape the second escape \ which escape \s.

And then if you want to have an array in output then you have to set assoc = true as second parameter for json_decode() function.

Read more about json_decode() function in documentation.

Solution

See the DEMO from my code.

<?php
$json = '{"regex":["Hello\\\s+World"]}';

$obj1 = json_decode($json);
echo $obj1->regex[0]."<br>";

$obj2 = json_decode($json, true); //When assoc == TRUE, returned objects will be converted into associative arrays.
echo $obj2["regex"][0];
?>

How to escape all JSON control characters:

Comments

1

Because of potentially complex regex and double escaping problem, you're not getting the string literal you are expecting.

This should work for any regex:

$regex1 = <<<EOD
Hello\s+World
EOD;

$obj = new stdClass();
$obj->regex = array();
$obj->regex[] = $regex1;

$json = json_encode($obj);

$decoded = json_decode($json);

var_dump($decoded->regex[0]);

output:

string(13) "Hello\s+World"

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.