JSON 文字列エスケープ / 解除
JSONJSON 文字列のエスケープと解除——引用符、制御文字、\uXXXX。
このページの内容
JSON 文字列のエスケープとは?#
JSON ドキュメントの中では、文字列は必ずダブルクォートの間に置かれます。そして、そのテキスト自体がクォート・改行・バックスラッシュを含む moment に問題が生じます。そのまま放り込むと、パーサーは閉じクォートを早すぎる位置で見つけたり、\ を解釈不能なエスケープの先頭と見なしたりします。エスケープとは、そうした文字を JSON 仕様が定める短いバックスラッシュ列に置き換えること——\" でクォート、\\ でバックスラッシュ、\n で改行、\t でタブ、といった具合です。エスケープ解除はその逆で、これらの列を元の文字に戻します。
さらに、より厳しいモードがもう一つあります。レガシーなシステム(古いログ転送ツール、制約の厳しいデータベース、純粋な ASCII を前提とするトランスポート層)は、127 を超えるバイトがあると正しく扱えません。そのために JSON は、任意の非 ASCII 文字を \uXXXX で書くことも許しています(絵文字のような astral 文字は UTF-16 サロゲートペアになります)。テキストは依然として有効な JSON です。たまたまエスケープ後にすべて ASCII で構成されているだけです。
このページは両方向・両モードに対応します。生文字列を有効な JSON 文字列リテラルへエスケープすることも、リテラルを元のテキストへエスケープ解除することもできます。さらに、すべての非 ASCII コードポイントを強制的に \uXXXX 形式にする**「ASCII のみ出力 (\uXXXX)」**スイッチも用意しています。
使い方#
- ツールバー左上のエンコード / デコード切り替えで方向を選びます。エンコードは生テキストを JSON リテラルにエスケープし、デコードはリテラルをテキストに戻します。
- 左側の入力ペインに入力または貼り付けを行います。
- エンコードでは、テキスト全体が 1 つの JSON 文字列リテラルになります(前後のクォートを含む)。
- デコードでは、クォート付きリテラル(
"a\nb")でも、エスケープ本体のみ(a\nb)でも貼り付け可能です。ツールがクォートを補って包みます。有効な JSON の数値・真偽値・オブジェクトは、暗黙に変換されるのではなく「文字列ではない」として拒否されます。
- 下流の処理系が非 ASCII バイトを扱えない場合は、ASCII のみ出力 (\uXXXX)(エンコードモード)にチェックを入れます。絵文字のような astral 文字は、
JSON.stringifyと同じく正しいサロゲートペアとして出力されます。 - 結果は出力ペインにリアルタイムで表示されます。コピーで取り出せます。
- サンプルは多言語混在のデモ文字列を流し込みます。クリアは両ペインをリセットします。
主な特徴#
- 仕様に正確な短縮形式。 RFC 8259 が要求するシーケンス(
\"、\\、\b、\f、\n、\r、\t)と、0x20 未満の残りすべてに\uXXXXを使い、JSON.stringifyとバイト単位で一致します。 - 本当の ASCII のみモード。 非 ASCII 文字は黙って削り落とされたり文字化けしたりしません。各文字は
\uXXXXとして出力され、astral 文字(U+FFFF 超)は正しい UTF-16 サロゲートペアになります。デコーダが拒否するような壊れた単独コードユニットにはなりません。 - 寛容なエスケープ解除。 クォート付きの完全なリテラルと、裸のエスケープ本体のどちらも受け付けます。ログ行から途中まで貼り付けた断片でも、例外を投げずにデコードできます。
- 推測しない。 デコード結果が有効な JSON であっても文字列でない場合(例えば裸の数値や配列)は、勝手に文字列化せず、その旨を通知します。
実例#
エンコードモードでサンプルを読み込むと、入力には意図的にクォート・バックスラッシュパス・改行・コピーライト記号・絵文字・中国語を混ぜた文字列が入ります:
He said "hi"
\path\ © 🌍 你好
ASCII のみをオフにすると、エスケープされたリテラルは読める文字をそのまま残し、クォートが必要な部分だけをクォートします:
"He said \"hi\"\n\\path\\ © 🌍 你好"
ここでASCII のみ出力 (\uXXXX) にチェックを入れると、同じ入力が純粋な ASCII になります——コピーライト記号は 4 文字の形式 \u00a9、地球の絵文字はサロゲートペア \ud83c\udf0d、各中国語文字はそれぞれのコードポイント(\u4f60、\u597d)に変換されます:
"He said \"hi\"\n\\path\\ \u00a9 \ud83c\udf0d \u4f60\u597d"
デコードに切り替えて、これらのリテラルのどちらかを貼り戻してください。絵文字や中国語を含め、元のテキストが正確に復元されます。
よくある質問#
絵文字が 1 つではなく 2 つの \u コードになるのはなぜですか?#
U+FFFF より大きい文字(絵文字、まれな CJK 拡張、一部の数学記号)は 1 つの 16 ビットコードユニットに収まらないため、UTF-16 ではサロゲートペア——上位サロゲートと下位サロゲートの組——として表現されます。地球の絵文字 🌍(U+1F30D)は \ud83c\udf0d になります。\u 1 つだけを出力すると、厳密なデコーダが拒否する無効な JSON になってしまいます。このツールは JSON.stringify と同じくペアを出力するため、結果は正しく往復変換できます。
デコードで「無効な JSON 文字列です。」と表示されます。何を貼りましたか?#
有効な JSON だが文字列ではないものを貼りました——典型的には裸の数値(42)、真偽値(true)、オブジェクトや配列です。ツールはこれを文字列化しません。それでは本当の間違いを隠してしまうからです(ほぼ間違いなく、ドキュメント全体ではなく文字列の値を貼るつもりだったはずです)。テキストをクォートで囲んでやり直してください。
リテラルのタブやベルなど制御文字は扱えますか?#
はい。入力のリテラルタブは \t、バックスペースは \b、フォームフィードは \f、復帰は \r になります。U+0020 未満の他の制御コード(ベルの 0x07 を含む)は \u0007 形式のコードになります。これは重要な点です。生の制御文字は JSON 文字列の中では不正であり、パーサによっては完全に拒否されるからです。
ASCII のみ出力は「より安全」ですか?#
特定の種類の安全——非 ASCII バイトを破壊・拒否するトランスポート層を生き延びる——に対してのみそうです。セキュリティ対策ではありません。データは依然として完全に可逆で、より制限の強い文字集合で表現されているだけです。消費側が ASCII を要求する場合に使い、そうでない場合は読みやすい形式のほうがデバッグしやすいためオフのままにしてください。