開発者ツール · JSON フォーマッタおよびバリデータ
JSON 文字列エスケープの説明: \n、\uXXXX、および制御文字
· 仕組み
json 開発者ワークフロー 検証
JSON 文字列内の生の改行は無効であり、タブも同様です。この投稿では、8 つのエスケープ シーケンス、 \u エスケープとサロゲート ペアの仕組み、および貼り付けられた段落がファイル全体を無効にする理由について説明します。
ペイロードを破壊した段落
ペイロードを分割した段落。引用符で囲まれた説明に表示される改行を貼り付けると、制御文字が JSON 文字列に直接挿入されます。最初の行は完了しているように見えますが、開始引用符にはまだ文字列コンテンツまたは終了引用符が必要です。 JSON 文字列は物理行にまたがることができないため、パーサーは生の改行に到達するとそこで停止します。テキストには、デコードされた値に改行が必要な場合は必ず 2 文字のエスケープ `\n` を含める必要があります。
ドキュメントまたはスプレッドシートからコピーされたタブは、エディターがタブを無害なスペースとして表示する場合でも、同じクラスの障害を引き起こします。リテラルのタブを `\t` に、キャリッジ リターンを `\r` に、その他の禁止されているコントロールを名前付きエスケープまたは Unicode エスケープに置き換えます。
JSON で許可される 8 つのエスケープ
JSON で許可される 8 つのエスケープ — バックスラッシュの後の短い形式は、`"`、`\\`、`\/`、`\b`、`\f`、`\n`、`\r`、および`\t`。これらは、引用符、バックスラッシュ、スラッシュ、バックスペース、フォーム フィード、ライン フィード、キャリッジ リターン、および水平タブを表します。スラッシュはエスケープされていないように見える場合もあります。 `\/` は主に、かつて終了スクリプト シーケンスを特別に扱っていたコンテキストとの互換性のために存在します。
JSON バックスラッシュの後に他の文字を続けることはできません。 `\v`、`\0`、`\x41`、またはバックスラッシュとそれに続く物理的な改行など、プログラミング言語でよく知られているシーケンスは、ここでは無効です。短いエスケープが存在しない場合は、`\u` の後に正確に 4 桁の 16 進数を続けて使用します。この小さな固定語彙により、JSON 文字列の移植性が維持されます。コンシューマは、有効なテキストで表される文字を判断するために JavaScript、Python、またはシェル固有のエスケープ ルールを必要としません。
リテラルのタブは無効だが、リテラルの é は問題ない理由
リテラルのタブは無効だが、リテラルの é は問題ない理由 — JSON は、文字列内の U+0000 から U+001F までのエスケープされていないコード ポイントを禁止します。その範囲には、タブ、改行、およびその他のコントロールが含まれており、それらの目に見えない効果によりフレームや表示が中断される可能性があります。文字 `é` は U+00E9 であり、制御範囲を大きく超えているため、UTF-8 JSON は引用符の間に直接これを含めることができます。ほとんどのスクリプト、記号、絵文字にも同じことが当てはまります。
したがって、通常の Unicode のエスケープはオプションであり、クリーンさの要件ではありません。 `"café"` と `"caf\u00e9"` は同じ文字シーケンスにデコードされます。通常、直接テキストの方が読みやすくなりますが、エスケープは ASCII のみのトランスポートに役立つか、特定のコード単位を表示できるようにすることができます。制御文字は異なります。エスケープが必須です。
\uXXXX エスケープの仕組み
`\uXXXX` エスケープの仕組み — `u` の後には、0 ~ 9 または A ~ F を使用して、正確に 4 桁の 16 進数が続く必要があります。 `\u00E9` は `é` の UTF-16 コード単位を表し、`\u000A` は改行を表します。桁数が少ない場合、`\u{1F600}` などの中括弧、または 16 進数以外の文字を使用すると、たとえ別のプログラミング言語がその表記法を受け入れていたとしても、JSON は無効になります。
U+FFFF より上の文字は、このエスケープ形式ではサロゲート ペアとして表されます。絵文字 😀 は、`\uD83D\uDE00` として記述できます。上位サロゲートと下位サロゲートは、1 つの Unicode スカラー値に解析された後に結合されます。 JSON 文法は、ペアになっていないサロゲート エスケープを保持できますが、完全な Unicode 文字を識別しないため、下流のエンコーダおよびアプリケーションがそれを拒否または置き換える可能性があります。
実用的な例: Windows パスと HTML のスニペットをエスケープする
うまくいった例: Windows パスと HTML のスニペットをエスケープする — 意図したパス `C:\Temp\report.txt` には、JSON ソース: `"C:\\Temp\\report.txt"` で各バックスラッシュが 2 つ必要です。二重にしないと、`\T` は無効なエスケープとなり、`\r` や `\t` などのシーケンスは、パス区切り文字の代わりに暗黙的に制御文字になる可能性があります。表示されたスラッシュがすでに外部言語に属していることを推測するのではなく、意図した値から JSON を構築します。
`<a title="Report">Open</a>` などの HTML フラグメントは、山括弧とスラッシュを文字通りに保持できますが、属性引用符は JSON 文字列内で `\"` になる必要があります。改行で 2 つのタグが区切られている場合は、`\n` としてエンコードします。結果の JSON メンバーは検証され、解析されて元の HTML テキストに戻されます。
エスケープが 2 倍になる場所
エスケープが 2 倍になる場合、すべての囲みテキスト文法がバックスラッシュを解釈する独自の機会を取得します。デコードされた文字列 `line1\nline2` を含む JSON ドキュメントは、バックスラッシュをエスケープして `"line1\\nline2"` を生成する必要があります。 JSON テキスト自体が JSON 文字列として保存されている場合、その引用符と両方のバックスラッシュには別のエスケープ層が必要です。明らかな乱雑さは、JSON の特別な拡張形式ではなく、複数の表現を記録します。
シェルとプログラミング言語リテラルは、JSON パーサーが引数を認識する前に、独自の引用符ルールを追加します。徹底的に診断します。最初に正確にデコードされた値を書き込み、それを JSON としてエンコードし、次にその完全な JSON テキストを周囲のシェルまたはソース言語にエンコードします。各境界で、次のパーサーが実際に受信するバイトまたは文字を検査します。
これでカバーされない内容
これでカバーされないもの — `"` などの HTML エンティティと `%20` などの URL パーセント エンコーディングは、別個の構文コンテキストに対する別個の変換です。 JSON パーサーはどちらの形式もデコードしません。文字列 `"""` には、解析後の 6 つのリテラル文字 (引用符ではなく) が含まれており、 `"%20"` には、パーセント記号とその後に続く 2 桁の数字 (スペースではありません) が含まれています。データが HTML または URL コンポーネントに入る場合にのみ、これらのエンコーディングを適用します。
この説明も、出力エンコーディングを置き換えるものではありません。信頼できないソースから受信した有効な JSON には、HTML、スクリプトのようなテキスト、または端末制御シーケンスが通常の文字列データとして含まれている可能性があります。後でコマンドをレンダリングまたは実行するアプリケーションは、その宛先を安全に処理する必要があります。 JSON エスケープは JSON 構造を保護します。それは普遍的な消毒ではありません。
要点: 文法で禁じられていることから逃れることは、それ以上のことではありません
要点: 文法で禁止されているものをエスケープするだけです。JSON 文字列内の二重引用符、バックスラッシュ、および U+0020 の下のコード ポイントには注意が必要です。通常の Unicode は読み取り可能なままですが、`\uXXXX` は正確な 4 桁の代替を提供し、サロゲート ペアは U+FFFF より上の文字を表します。明らかに空白の位置の診断では、多くの場合、テキストのエスケープで置き換える必要があるリテラルの改行、タブ、またはその他の制御文字が特定されます。
スラッシュを目視で数えるのではなく、エンコード層を数える。アプリケーションが受け取る必要がある値から開始し、それを JSON に対して 1 回エンコードし、その後、結果のドキュメントを外部シェル、ソース ファイル、または 2 番目の JSON 文字列に対して引用します。 JSON パーサーに提示されたテキストを検証し、正確性が重要な場合は、後でデコードされた文字列を検査します。