JSONフォーマッター
スペース2個・4個・タブでJSONを整形。数字は1桁も変えません。
貼り付けたものがブラウザの外に出ることはありません。 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行にまとめる整形ツールもありますが、こちらは一貫した書式にしています。行数は増えますが、差分ははるかに読みやすくなります。