Как проверить, является ли строка корректной JSON-строкой?
У меня есть функция isJsonString
, которая должна проверять, является ли переданная строка корректной JSON-строкой. Например, следующий код:
isJsonString('{ "Id": 1, "Name": "Coke" }')
должен возвращать true
, а вот эти строки:
isJsonString('foo')
isJsonString('<div>foo</div>')
должны возвращать false
.
Я ищу решение, которое не использует блоки try
/catch
, так как моя отладка настроена на "прерывание на всех ошибках", и это приводит к прерыванию выполнения при встрече некорректных JSON-строк. Как я могу реализовать такую проверку?
5 ответ(ов)
Я понимаю, что я опоздал с ответом на этот вопрос на три года, но мне захотелось высказаться.
Хотя решение 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;
};
Надеюсь, это поможет кому-то ещё!
В вашем коде представлена функция для проверки, является ли строка корректным 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 и определения, является ли значение массивом или объектом.
Вот ваш рабочий код на 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
или примитив (например, строку или число). Если вам нужно
Я использовал действительно простой метод для проверки, является ли строка действительным 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 — это объект.
Этот метод работает всегда. 😃
Я, кажется, опоздал на вечеринку. Вот что я в итоге сделал. Использование простой проверки с помощью регулярных выражений значительно повышает производительность:
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-строками, но я целенаправленно игнорирую их для простоты. Для более тщательной предварительной проверки добавьте дополнительные условия в зависимости от вашего случая использования.
Красивый вывод JSON с помощью JavaScript
Безопасное преобразование строки JSON в объект
Преобразование объекта JS в строку JSON
Как сравнить массивы в JavaScript?
Как прочитать JSON-файл в память сервера?