本文へスキップ
jsonbeautifiers
日本語

JSONフォーマッター

スペース2個・4個・タブでJSONを整形。数字は1桁も変えません。

JSONPathで絞り込む

RFC 9535の構文です。結果は、このダイアログを開いたパネルを置き換えます。

 

貼り付けたものがブラウザの外に出ることはありません。 connect-src の許可リストにより、これは約束ではなくブラウザによる保証になっています。 自分で確かめる

JSONの整形とは、人間には必要でマシンには不要な空白を加えることです。1行に1メンバー、一貫したインデント、コロンのあとに空白をひとつ。データそのものは変わりません。変わるのは見た目だけです。

そして、その最後の一文こそが間違えやすいところです。ドキュメントをJavaScriptの値としてパースし、それを再度シリアライズする整形ツールは、何かを出力する前にすでにあなたの数値を書き換えています。世の中の大半はまさにそれをやっています。

整形で変わらないもの

この整形ツールは、パース済みの値を再シリアライズするのではなく、読み取ったトークンをそのまま出し直します。つまり、すべての数値・文字列・リテラルのテキストはバイト単位でそのまま戻り、書き換わるのはその間の空白だけです。

これは聞こえる以上に重要です。19桁のIDを含むドキュメントを、JSON.parseとJSON.stringifyの上に作られた整形ツールに通すと、IDは静かに別の値になって返ってきます。画面のどこにも警告は出ません。

数値は元のテキストのまま
1.50は1.50のまま、1e3は1e3のまま、-0は-0のまま、そして12345678901234567890は12345678901234567000にならず、そのままの値で残ります。
文字列はそのまま複製される
エスケープされた\u00e9はエスケープされたまま、リテラルのéはリテラルのままです。文字列をどうエンコードすべきかを決めるのは整形の役目ではないので、決めません。
キーの順序は保たれる
明示的にソートを有効にしないかぎりは保たれます。仕様上、JSONのオブジェクトは順序を持ちませんが、実際にはどのパーサーも挿入順を保持しており、差分はそれに依存しています。
重複キーは残したうえで警告する
片方を削除すると、受け取る側から見える内容が変わってしまいます。代わりに、両方の位置を示した警告が表示されます。

どのインデントを選ぶか

ここでの既定値はスペース2個です。npm、Prettier、そしてJavaScript系ツールのほとんどがそれを出力し、またJSONの入れ子はすぐ深くなるからです。浅い設定ファイルならスペース4個のほうが読みやすくなります。タブは読む人それぞれが幅を選べるため、アクセシビリティの観点からは有利で、圧縮率もわずかに良くなります。

読むためではなく送るためのデータなら、整形ではなく圧縮してください。JSONレスポンス中の空白は純粋なオーバーヘッドで、一般的なAPIのペイロードではバイト数の10〜20パーセントを占めます。

改行コードと末尾の改行

出力は既定でLFを使います。CRLFのオプションがあるのは、Windowsのツールや一部のCIがそれを気にするからであり、また両方が混ざったファイルは、すべての行が変更されたように見える差分を生むからです。

文字列の外側の空白はパーサーにとって無意味なので、ここまでの話は妥当性には影響しません。影響するのは差分であり、実際に目につくのはそちらです。

How to do this in code

同じ処理をコードで書いた場合です。いずれもスペース2個のインデントを生成します。そして、いずれもあなたの数値を書き換えます。ペイロードに大きな整数が含まれていないときに受け入れる取引です。

js JavaScript

第3引数には、スペースの個数か、インデント単位として使う文字列を渡せます。

const pretty = JSON.stringify(JSON.parse(text), null, 2);

// Tabs
const tabbed = JSON.stringify(JSON.parse(text), null, '\t');
py Python

ensure_asciiの既定値はTrueで、アクセント付き文字をすべて\uエスケープに変換します。それを望む人はほとんどいません。

import json

pretty = json.dumps(json.loads(text), indent=2)

# Keep non-ASCII readable rather than escaping it
pretty = json.dumps(json.loads(text), indent=2, ensure_ascii=False)

# From the command line
# python -m json.tool --indent 2 input.json
sh jq

jqは既定では何もソートしません。キーをソートするには-Sを付けます。

jq . input.json              # 2 spaces, the default
jq --indent 4 . input.json
jq --tab . input.json
jq -c . input.json           # compact
go Go

json.Indentは、標準ライブラリの中でこのページの動作にもっとも近いものです。値をデコードせずにバイト列を整形し直します。

var buf bytes.Buffer
if err := json.Indent(&buf, data, "", "  "); err != nil {
    return err
}

// json.Indent works on raw bytes, so unlike Unmarshal it does
// not touch your numbers at all.
rb Ruby
require 'json'

pretty = JSON.pretty_generate(JSON.parse(text))
php PHP

PHPはスペース4個でインデントし、これらのフラグを渡さないかぎりスラッシュとUnicodeをエスケープします。

$pretty = json_encode(
    json_decode($text),
    JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE
);

よくある質問

サイズ制限はありますか?
このページ側の制限はありません。実際の上限はブラウザです。JavaScriptエンジンは単一の文字列を約512MBに制限しているため、それより大きいものはそもそも保持できません。10MBのドキュメントの整形にはここで約780ミリ秒の処理が必要ですが、バックグラウンドのワーカーで実行されるためページの操作性は保たれます。
整形するとデータが変わりますか?
変わりません。文字列の外側の空白はJSONでは意味を持たず、この整形ツールはパースして再シリアライズするのではなく、書かれたとおりの値をそのまま出し直します。キーのソートを有効にした場合はドキュメントが変わるため、既定ではオフになっています。
整形結果がエディタの出力と違うのはなぜですか?
たいていは末尾の改行か、オブジェクトの配列の書き方の違いです。短い配列を1行にまとめる整形ツールもありますが、こちらは一貫した書式にしています。行数は増えますが、差分ははるかに読みやすくなります。