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.

Bharata
  • 13,509
  • 6
  • 36
  • 50
StackOverflowNewbie
  • 39,403
  • 111
  • 277
  • 441

3 Answers3

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.

Sammitch
  • 30,782
  • 7
  • 50
  • 77
2

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:

Bharata
  • 13,509
  • 6
  • 36
  • 50
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"
Boy
  • 1,182
  • 2
  • 11
  • 28