PHP: регулярное выражение в JSON вызывает проблемы для json_decode? - PullRequest
0 голосов
/ 19 января 2019

У меня есть несколько регулярных выражений в моем JSON, что не вызывает проблем при тестировании моего JSON на онлайн-валидаторе JSON. Однако, когда я беру эту строку JSON и пытаюсь json_decode() в PHP, я получаю JSON_ERROR_SYNTAX .

Есть идеи, почему? И как мне это решить?

Пример кода:

<?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;
}

Проблема в \s. Изменение его на \\s не помогает.

Ответы [ 3 ]

0 голосов
/ 22 января 2019

Ваша строка "Hello\s+World" должна быть экранирована как "Hello\\\s+World". Первый побег \ предназначен для побега, второй побег \ сбежит \s.

И затем, если вы хотите иметь массив в выводе, вы должны установить assoc = true в качестве второго параметра для функции json_decode().

Подробнее о json_decode() функциях в документации .

Решение

См. DEMO из моего кода.

<?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];
?>

Как экранировать все управляющие символы JSON:

0 голосов
/ 23 января 2019

Из-за потенциально сложной задачи регулярного выражения и двойного экранирования вы не получаете ожидаемый строковый литерал.

Это должно работать для любого регулярного выражения:

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

вывод :

string(13) "Hello\s+World"
0 голосов
/ 19 января 2019

Когда вы пишете "\s" в PHP, буквальная строка равна \s, потому что \s не является допустимой escape-последовательностью.

Когда вы пишете "\\s" в PHP, буквальная строка равна \s, потому что \\ - это допустимая escape-последовательность.

JSON, с другой стороны, выдаст ошибку для недопустимых escape-последовательностей, что является вашей проблемой.

Решение: Не пишите JSON вручную.

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

Вывод: {"regex":["Hello\\s+World"]} [примечание: буквенная строка, допустимый JSON]

Плохое решение - это больше проблем, чем стоит, и, вероятно, вызовет проблемы в будущем: "Hello\\\s+World" добро пожаловать в побег из ада.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...