プロパティの引用符なしのJSON.stringify?


95

正しくないJSON形式を使用するサービスを使用しています(プロパティを二重引用符で囲みません)。だから私は送る必要があります

{ name: "John Smith" } の代わりに { "name": "John Smith" }

これは私のサービスではないため、この形式は変更できません。

上記のような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" }'

修正してくれたRob Wに感謝します。

制限事項

通常の場合、前述の正規表現は機能しますが、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"}(...)になります!
Rob W

1
@Derek /\\\"/はに簡略化できます/\\"/。グローバルフラグを追加することを忘れないでください。そうしないと/\\"/g、複数のを含む文字列で中断します\"。ランダムな文字については、決してエディタチョーク場合には、リテラルU + FFFFを使用しませんが、エスケープシーケンス。元に戻すための正規表現はになり/\uFFFF/gます。
Rob W

2
@Derek読取會功夫あなたの正規表現/\"([^(\")"]+)\":/gはに簡略化できます。regex101.com/"([^"]+)":/g
r / qnz0ld /

1
@endriuその場合は、null値のチェックを追加するだけです。
Derek款會功夫2018

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ニューマン2015

3
util.inspect()オブジェクトをNeo4jクエリに書き込んでいるときに、複数のパラメーターを一度に設定できるようになりました。
agm1984 2017

1
nodejsリンクから:> util.inspect()メソッドは、デバッグ用のオブジェクトの文字列表現を返します。util.inspectの出力はいつでも変更される可能性があり、プログラムで依存すべきではありません。
Peter Roehlen、2018年

5

JSON形式を定義したパーサーが作成したパーサーのソースコードを見ることができます。関数呼び出しを探します。これらは値を引用符で囲みます。キーは、326行目と338行目で引用されています。json2.js quote

変更後のライブラリは含めないでください。代わりに、関連する(stringify)部分のみを取るか、少なくともJSON他のもので置き換えてください。FAKEJSON

たとえば、以下FAKEJSONのみを定義したオブジェクトstringifyhttp : //jsfiddle.net/PYudw/


純粋なJavaScriptで実行できるのに、なぜ追加のライブラリが必要なのでしょうか。
Derek━會功夫

これは良い考えです。私は、レポをフォーク引用符を削除し、それはあなたがしていることを明確にするFAILJSONような何かの冗談にJSONオブジェクトの名前を変更するだろうではない実際のJSONオブジェクト、または実際のJSONを扱います。
RichardTowers

@Derekライブラリ全体を含めないでください。JSON.stringify一部だけを取り、引用符を削除します。ライブラリはJSONを定義したものによって作成されているため、結果が非​​常に有効なJSONであることがかなり確実になります。
Rob W

これが最良のアプローチのようです。
Derek━會功夫

ええ、デレクに同意します。彼の代わりはうまく機能しますが、私はクロフォードのコードに自信を持っています。 .toSource()正常に動作しますが、オブジェクトが配列内にある場合は含まれません(そして、私はノード上にいるので、ブラウザの互換性は問題ではありません:P)。@ RobWのおかげで、このメソッドを使用します。jsfiddleリンクのようですローディングページで立ち往生する:(
NiCk Newman '29

3

JSONPでサービスを使用してみてください。この形式を使用すると、サービスが提供されると思います。

それ以外の場合は、なぜが規格に準拠する必要があるのか​​についての適切な議論を含む詳細なバグレポートを提出してください。ソースの問題を排除する以外のソリューションは、実際のソリューションではありません。

文字列を解析する前に、正規表現を介して文字列をパイプ処理することで、すばやくnダーティに修正できます。

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

または、より構文的な解析が必要な場合は、既存のjavascript JSONパーサー(この例のような)を調整してみてください。




2

このメソッドを共有していただきありがとうございます。オブジェクトの配列の文字列化をサポートするコードも共有したいと思います。

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.stringifyinstanceof Dateも使用する必要があります。がnullの'null'場合も返しobj_from_jsonます。
Far Dmitry

1
:条件はこのように見える場合、私はちょうど秒を変更することにより、@FarDmitryが提起したポイントを固定if(typeof obj_from_json !== "object" || obj_from_json instanceof Date || obj_from_json === null)
Brunno Vodolaマーチン

2

使用する JSON5.stringify

JSON5は、引用符で囲まれていないプロパティキーを含むES5構文を許可するJSONのスーパーセットです。JSON5リファレンス実装(json5npmパッケージ)はJSON5、組み込みJSONオブジェクトと同じ引数とセマンティクスを持つ同じメソッドを持つオブジェクトを提供します。

使用しているサービスがこのライブラリを使用している可能性が高いです。


1

CSVJSONのJSON Beautifierには、キーの引用符を削除するオプションがあります。コードだけが必要な場合は、GitHubリポジトリからコピーできます。Douglas CrockfordのJSON2変更して、サポートを追加しました。


csvjson.com/json_beautifierをクリックしただけで、予想とは異なるページが表示されました... hacked by AnoaGhost
RedactedProfile

片付けました。ご不便おかけしてすみません。
Martin Drapeau 2016
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.