JSON.stringify без лапок на властивості?


95

Я використовую службу, яка використовує неправильний формат JSON (немає подвійних лапок навколо властивостей). Тож мені потрібно відправити

{ name: "John Smith" } замість { "name": "John Smith" }

Цей формат не можна змінити, оскільки це не моя послуга.

Хто-небудь знає про маршрутизацію stringify для форматування об’єкта JavaScript, як вище?

Відповіді:


115

Це просте рішення регулярних виразів працює, щоб у більшості випадків зняти назви властивостей JSON:

const object = { name: 'John Smith' };
const json = JSON.stringify(object);  // {"name":"John Smith"}
console.log(json);
const unquoted = json.replace(/"([^"]+)":/g, '$1:');
console.log(unquoted);  // {name:"John Smith"}

Екстремальний випадок:

var json = '{ "name": "J\\":ohn Smith" }'
json.replace(/\\"/g,"\uFFFF");  // U+ FFFF
json = json.replace(/"([^"]+)":/g, '$1:').replace(/\uFFFF/g, '\\\"');
// '{ name: "J\":ohn Smith" }'

Особлива подяка Робу В. за виправлення.

Обмеження

У звичайних випадках вищезазначений регулярний вираз буде працювати, але математично неможливо описати формат JSON регулярним виразом, щоб він працював у кожному окремому випадку (підрахування однакової кількості фігурних дужок неможливе для регулярного виразу.) Тому я маю створити нову функцію для видалення лапок, формально проаналізувавши рядок JSON за допомогою власної функції та повторно її проаналізувавши:

function stringify(obj_from_json) {
    if (typeof obj_from_json !== "object" || Array.isArray(obj_from_json)){
        // not an object, stringify using native function
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    let props = Object
        .keys(obj_from_json)
        .map(key => `${key}:${stringify(obj_from_json[key])}`)
        .join(",");
    return `{${props}}`;
}

Приклад: https://jsfiddle.net/DerekL/mssybp3k/


3
-1 - це теж не я, але ви повинні уважно прочитати питання. OP повинен кодувати об'єкт у (зламаному) json, а не аналізувати / оцінювати його.
Salman A

7
@Derek Цей метод не є надійним . Наприклад, візьмемо цей вхід: {"foo":"e\":bar"}(дійсний JSON) стає {foo:e:bar"}(...)!
Роб W

1
@Derek /\\\"/можна спростити до /\\"/. Не забудьте додати глобальний прапор, /\\"/gінакше він розірветься на рядки з кількома \". Що стосується випадкового символу, ніколи не використовуйте літерал U + FFFF, на випадок, якщо редактор задихається, а послідовність виходу. Регулярний вираз для скасування став би /\uFFFF/g.
Роб В.

2
@Derek 朕 會 功夫 ваш регулярний вираз /\"([^(\")"]+)\":/gможна спростити /"([^"]+)":/g, див. Regex101.com/r/qnz0ld/2
tanguy_k

1
@endriu У цьому випадку просто додайте додаткову перевірку на нульові значення.
Дерек 朕 會 功夫

18

Схоже, це простий метод Object toString, який ви шукаєте.

У Node.js це вирішується за допомогою об'єкта util і виклику util.inspect (yourObject). Це дасть вам усе, що ви хочете. перейдіть за цим посиланням, щоб отримати більше варіантів, включаючи глибину застосування методу. http://nodejs.org/api/util.html#util_util_inspect_object_options

Отже, те, що ви шукаєте, - це в основному інспектор об’єктів, а не перетворювач JSON. Формат JSON визначає, що всі властивості повинні бути укладені в подвійні лапки. Отже, не буде перетворювачів JSON, щоб робити те, що ви хочете, оскільки це просто не формат JSON. Специфікації тут: https://developer.mozilla.org/en-US/docs/Using_native_JSON

Заперечення рядка або перевірки - це те, що вам потрібно, залежно від мови вашого сервера.


1
Дуже тобі дякую! Це саме те, що я шукав. Я використовую json для передачі даних через сервер ws до моєї гри і вірю чи ні, без необхідності мати справу з зайвими лапками навколо назв властивостей економить величезну кількість даних! Тільки для уточнення, .toSource()чудово працює і в nodejs, але не працює з об’єктами в масивах. Перевірка utilпрацює для масивів та об’єктів у масивах, що чудово, дуже подобається.
NiCk Newman

3
util.inspect()просто чудово працював для мене під час запису об’єкта в запит Neo4j для встановлення декількох параметрів одночасно.
agm1984

1
За посиланням nodejs:> Метод util.inspect () повертає рядкове представлення об'єкта, призначеного для налагодження. Вихід util.inspect може змінитися в будь-який час і не повинен залежати програмно.
Пітер Ролен,

5

Ви можете переглянути вихідний код парсера, створений тим, хто визначив формат JSON . Шукайте виклики функцій: вони оточують значення лапками. Ключі наводяться в рядках 326 та 338 .json2.js quote

Не включайте бібліотеку після модифікації. Замість цього візьміть лише відповідну ( stringify) частину або, принаймні, замініть JSONчимось іншим, наприклад. FAKEJSON.

Наприклад, об’єкт, FAKEJSONякий лише визначив stringify: http://jsfiddle.net/PYudw/


Навіщо вам потрібна додаткова бібліотека, коли ви можете це робити в чистому JavaScript?
Дерек 朕 會 功夫

Це гарна ідея. Я б розгалужив репо, видалив лапки та перейменував об’єкт JSON на щось вигадливе, як FAILJSON, щоб було зрозуміло, що ви не працюєте з фактичним об’єктом JSON або фактичним JSON.
RichardTowers

@Derek Бібліотека не повинна бути включена як ціла. Візьміть лише JSON.stringifyчастину та видаліть лапки. Оскільки бібліотека створена тим, хто визначив JSON , ми можемо бути впевнені, що результат є дуже дійсним JSON.
Роб W

Схоже, це найкращий підхід.
Дерек 朕 會 功夫

Так, погодьтеся з Дереком. Хоча його замінник працює нормально, я почуваюся впевненіше в коді Кроуфорда, не маючи неповаги до Дерека Лол. .toSource()працює добре, але не включає, якщо ваш об'єкт знаходиться в масиві, який є обломним (і я на вузлі, тому compat браузера не є проблемою: P), тому я буду використовувати цей метод, дякуючи @RobW, також, здається, посилання jsfiddle застрягти на сторінці завантаження :(
NiCk Newman

3

Спробуйте використовувати сервів з JSONP, я думаю, вони пропонують його при використанні цього формату.

В іншому випадку подайте їм детальний звіт про помилку, включаючи хорошу аргументацію, чому це повинно відповідати стандарту. Будь-яке інше рішення, крім усунення проблеми джерела, не є реальним рішенням.

Швидким виправленням може бути передача рядка через регулярний вираз перед його синтаксичним аналізом:

var obj = JSON.parse(str.replace(/(\{|,)\s*(.+?)\s*:/g, '$1 "$2":'));

Або ви намагаєтесь налаштувати існуючий синтаксичний синтаксичний синтаксичний аналізатор JSON (як цей ), якщо ви хочете отримати синтаксичний синтаксичний аналіз.




2

@Derek 朕 會 功夫 Дякуємо, що поділилися цим методом, я хотів би поділитися своїм кодом, який також підтримує розшифрування масиву об’єктів.

export const stringifyObjectWithNoQuotesOnKeys = (obj_from_json) => {
    // In case of an array we'll stringify all objects.
    if (Array.isArray(obj_from_json)) {
        return `[${
                    obj_from_json
                        .map(obj => `${stringifyObjectWithNoQuotesOnKeys(obj)}`)
                        .join(",")
                }]` ;
    }
    // not an object, stringify using native function
    if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null){
        return JSON.stringify(obj_from_json);
    }
    // Implements recursive object serialization according to JSON spec
    // but without quotes around the keys.
    return `{${
            Object
                .keys(obj_from_json)
                .map(key => `${key}:${stringifyObjectWithNoQuotesOnKeys(obj_from_json[key])}`)
                .join(",")
            }}`;
};

1
Ви також повинні використовувати, JSON.stringifyнаприклад, Date. Також поверніть, 'null'якщо obj_from_jsonмає значення null.
Далекий Дмитро

1
Я щойно виправив очки, підняті @FarDmitry, змінивши другу умову if, щоб виглядати так:if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null)
Brunno Vodola Martins

2

Використовуйте JSON5.stringify

JSON5 - це набір JSON, що дозволяє синтаксис ES5, включаючи ключі властивостей без котирувань . Довідкова реалізація JSON5 ( json5пакет npm ) надає JSON5об’єкт, який має ті самі методи з тими ж аргументами та семантикою, що і вбудованийJSON об’єкт.

Дуже ймовірно, що послуга, якою ви користуєтесь, використовує цю бібліотеку.


1

JSON Beautifier CSVJSON має можливість скидати лапки на клавіші. Якщо вам потрібен лише код, ви можете скопіювати його з репозитарію GitHub. Я модифікував JSON2 Дугласа Крокфорда, щоб додати підтримку для цього.


Просто натиснув csvjson.com/json_beautifier і отримав іншу сторінку, ніж я очікував ... hacked by AnoaGhost
RedactedProfile

Прибрали зараз. Вибачте за незручності.
Martin Drapeau
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.