8

Как проверить, является ли строка корректной JSON-строкой?

1

У меня есть функция isJsonString, которая должна проверять, является ли переданная строка корректной JSON-строкой. Например, следующий код:

isJsonString('{ "Id": 1, "Name": "Coke" }')

должен возвращать true, а вот эти строки:

isJsonString('foo')
isJsonString('<div>foo</div>')

должны возвращать false.

Я ищу решение, которое не использует блоки try/catch, так как моя отладка настроена на "прерывание на всех ошибках", и это приводит к прерыванию выполнения при встрече некорректных JSON-строк. Как я могу реализовать такую проверку?

5 ответ(ов)

6

Я понимаю, что я опоздал с ответом на этот вопрос на три года, но мне захотелось высказаться.

Хотя решение Gumbo работает отлично, оно не учитывает несколько случаев, когда исключение не возникает при JSON.parse({что-то, что не является JSON}).

Мне также больше нравится возвращать распарсенный JSON одновременно, чтобы вызывающему коду не приходилось вызывать JSON.parse(jsonString) второй раз.

Вот что хорошо работает для моих нужд:

/**
 * Если вам не важны примитивы и нужны только объекты, то эта функция для вас,
 * в противном случае ищите что-то другое.
 * Эта функция вернет `false` для любого валидного JSON-примитива.
 * Например, 'true' -> false
 *            '123' -> false
 *            'null' -> false
 *            '"Я строка"' -> false
 */
function tryParseJSONObject(jsonString) {
    try {
        var o = JSON.parse(jsonString);

        // Обработка случаев, когда исключения не возникают:
        // Ни JSON.parse(false), ни JSON.parse(1234) не выбрасывают исключений,
        // поэтому у нас есть проверка типа. Но... JSON.parse(null) возвращает null,
        // а typeof null === "object", поэтому нам нужно проверять и это. К счастью, null является ложным значением,
        // так что этого достаточно:
        if (o && typeof o === "object") {
            return o;
        }
    }
    catch (e) { }

    return false;
};

Надеюсь, это поможет кому-то ещё!

0

В вашем коде представлена функция для проверки, является ли строка корректным JSON. Вот реализация на ванильном JavaScript:

// vanillaJS
function isJSON(str) {
    try {
        return (JSON.parse(str) && !!str);
    } catch (e) {
        return false;
    }
}

Использование: isJSON({}) вернет false, в то время как isJSON('{}') вернет true.

Чтобы проверить, является ли переданное значение массивом или объектом (то есть распарсенным JSON), можно использовать следующую реализацию:

// vanillaJS
function isAO(val) {
    return val instanceof Array || val instanceof Object;
}

// ES2015
var isAO = (val) => val instanceof Array || val instanceof Object;

Использование: isAO({}) вернет true, тогда как isAO('{}') вернет false.

Таким образом, вы можете использовать эти функции для проверки корректности JSON и определения, является ли значение массивом или объектом.

0

Вот ваш рабочий код на JavaScript, который проверяет, является ли строка корректной JSON-строкой:

function IsJsonString(str) {
  try {
    var json = JSON.parse(str);
    return (typeof json === 'object');
  } catch (e) {
    return false;
  }
}

Функция IsJsonString принимает строку str в качестве аргумента и пытается распарсить её с помощью JSON.parse(). Если строка является корректной JSON-строкой, функция вернет true, в противном случае — false.

Обратите внимание, что возвращаемый true подтверждает, что результат парсинга — это объект, поскольку JSON может представлять как объекты, так и массивы (которые также являются объектами в JavaScript). Это значит, что ваша функция вернет false, если строка представляет собой JSON-значение типа null или примитив (например, строку или число). Если вам нужно

0

Я использовал действительно простой метод для проверки, является ли строка действительным JSON или нет.

Вот код функции:

function testJSON(text){
    if (typeof text !== "string"){
        return false;
    }
    try {
        var json = JSON.parse(text);
        return (typeof json === 'object');
    } catch (error) {
        return false;
    }
}

Результат с допустимой строкой JSON:

var input = '["foo","bar",{"foo":"bar"}]';
testJSON(input); // возвращает true;

Результат с простой строкой:

var input = 'This is not a JSON string.';
testJSON(input); // возвращает false;

Результат с объектом:

var input = {};
testJSON(input); // возвращает false;

Результат с null:

var input = null;
testJSON(input); // возвращает false;

Последний вызов возвращает false, потому что тип переменной null — это объект.

Этот метод работает всегда. 😃

0

Я, кажется, опоздал на вечеринку. Вот что я в итоге сделал. Использование простой проверки с помощью регулярных выражений значительно повышает производительность:

if(/^\s*(\{|\[)/.test(str)){
    try{
        JSON.parse(str);
        // делаем что-то здесь или возвращаем obj/true
    }catch(e){
        // ничего не делаем или возвращаем false
    }
}

Регулярное выражение проверяет, начинается ли строка с [ или {. Это позволит устранить большинство ложных случаев (но не все). Вот быстрое тестирование производительности для вас: https://jsbench.me/awl6fgn8jb/1

В худшем случае этот метод может быть на 10-15% медленнее, чем прямое использование try, при этом худший случай подразумевает, что все строки являются валидными JSON-строками.

В лучшем случае это будет на 99% быстрее, чем чистый try, причем лучший случай означает, что все строки - недействительный JSON.

Этот метод проверяет только строки, которые можно разобрать в объекты или массивы. Обратите внимание, что строковые js-примитивы, такие как "true", являются действительными JSON-строками, но я целенаправленно игнорирую их для простоты. Для более тщательной предварительной проверки добавьте дополнительные условия в зависимости от вашего случая использования.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь