🪢 文字列エスケープ・アンエスケープ
HTML エンティティ・JavaScript 文字列・JSON 文字列・Unicode(\uXXXX)・URL の各形式で文字列を相互変換します。
📖 変換例
| Format | Raw | Escaped |
|---|---|---|
| HTML | <a> | <a> |
| JS | It's 'ok' | It\'s \'ok\' |
| JSON | tab here | tab\there |
| Unicode | 日本語 | \u65e5\u672c\u8a9e |
| URL | a b&c | a%20b%26c |
📖 つまずきやすいポイント
HTML エンティティ・JavaScript 文字列・JSON・Unicode (\uXXXX)・URL・CSV・SQL・正規表現・シェルなど 14 種類の形式で、文字列をエスケープ / アンエスケープします。処理はブラウザ内で完結します。ただしエスケープは「文字列を変換する作業」ではなく「出力先の文法に合わせる作業」です — このツールはあなたの出力先を知らないので、どの形式を選ぶべきかは判定できません。そして間違った形式を適用することは、何もしないことより悪い結果になります。安全になった気がするのに、実際には守られていないからです。
| ケース | 何が起きるか | どうする |
|---|---|---|
| 文脈が違えば正解のエスケープも違う | 同じ値でも、置かれる場所ごとに必要な処理が違います。<div> の中ならエンティティ化で足りますが、href="..." の中では URL としての妥当性も要求され、onclick="..." の中では JavaScript と HTML の 2 層を同時に満たす必要があります。さらに、HTML エスケープがまったく効かない文脈もあります — href に javascript: で始まる値が入ればエンティティ化しても実行されますし、<style> の中や <script> の中では < はただの文字として扱われるだけで、構文は閉じたままです。「とりあえず HTML エスケープ」が通用しない場所があるということです。 |
エスケープは出力の瞬間に、テンプレートエンジンにやらせてください。 Twig の |e('html_attr') / |e('js') / |e('url')、React の JSX、Go の html/template のように、文脈を指定できる仕組みを使うのが正解です。入力時にエスケープして保存する設計は捨ててください — 保存した値の出力先は 1 つとは限らず、メール本文にも CSV にも API の JSON にも流れます。データベースには常に生の値を入れ、出力のたびにその場の文脈でエスケープする。この 1 本の原則で、上に挙げた問題はほぼ全部消えます。このツールはその結果が正しいかを目視で確かめる場として使ってください。 |
二重エスケープ (&lt; が画面に出る) |
画面に <strong> や & がそのまま見えている状態です。原因はほぼ常に「2 回エスケープした」ことで、典型は 保存時にアプリがエスケープし、表示時にテンプレートエンジンがもう一度エスケープする組み合わせです。怖いのは、これがバグとして目立たないことです — 英数字だけのデータでは何も起きず、アポストロフィや & を含む名前が入力された行だけが壊れます。しかも壊れたデータは既にデータベースの中にあるので、表示側を直しても直りません。逆向きの事故もあります: JSON の \n がもう一度エスケープされて \\n になり、改行のはずが画面に 2 文字として現れるケースです。 |
まず、どちら側で二重になっているのかを切り分けてください。 データベースの値をそのままここに貼り、「アンエスケープ」方向で HTML を選びます。ここで値が変化したら、保存されている時点で既にエスケープ済み — 原因は入力側です。変化しなければ、二重化しているのは表示側です。修復は 1 回だけ実行するマイグレーションで行い、必ず対象を絞ってください (WHERE body LIKE '%&%')。全行に無条件で html_entity_decode をかけると、もともと正しく & と書きたかった行を壊します。実行前に必ずバックアップを取り、件数を数えてから流してください。 |
| エスケープはサニタイズではない | HTML エスケープは「テキストとして安全に表示する」処理であって、ユーザーが書いた HTML を安全に描画する処理ではありません。リッチテキスト投稿のようにタグを許したい場面では、許可するタグと属性を列挙するサニタイザが必要です。同じ誤解は他の形式にもあります。SQL 文字列のエスケープ ('') は、プレースホルダの代わりにはなりません — テーブル名や列名、ORDER BY の方向、LIKE のワイルドカード % と _ はどれも文字列エスケープの守備範囲外です。シェルのクォートも同様で、値が -rf のようにオプションとして解釈される場面は、引用符では防げません。 |
目的ごとに使う道具を変えてください。 タグを許すなら専用のサニタイザ (PHP なら HTML Purifier、JS なら DOMPurify) を使い、自作の正規表現でタグを除去しようとしないこと — この方向の自作は例外なく破られます。SQL は常にプレースホルダを使い、テーブル名や並び順のように束縛できない部分は、必ず許可リストと突き合わせてください (['name','created_at'] に含まれる値だけを通す)。シェルは配列形式で引数を渡す API (execve 系、Python の subprocess.run([...])) を使い、ユーザー入力の前に -- を置いてオプション解釈を打ち切ります。 |
Unicode エスケープには BMP 外という落とし穴があります。\uXXXX は 16 ビットしか表せないので、絵文字や一部の漢字はサロゲートペアとして 2 つに割れます — 絵文字 1 文字が \ud83d\ude00 の 2 個になるということです。ここで文字数を数えたり途中で切ったりすると、文字が半分に割れて壊れます。ES6 以降なら \u{1f600} という 1 個の形式が使えます。もうひとつ、この「非 ASCII が \uXXXX に化ける」性質は検証を妨げます — このサイト自身、テンプレートが JS 用にエスケープした文字列を日本語のまま grep して「デプロイされていない」と 2 回誤判定しました。正しい手順は、検索する前に \uXXXX を復号することです。最後にひとつだけ守ってほしいこと: アンエスケープした文字列を eval や JSON.parse 以外の実行系に渡さないでください。復号は検査のための操作であって、実行のための操作ではありません。
📖 使い方
-
1
形式と方向を選択変換形式(HTML / JavaScript / JSON / Unicode / URL など)とエスケープ・アンエスケープの方向を選択します。
-
2
テキストを入力左側の入力欄にテキストを貼り付けるか入力します。リアルタイムで変換されます。
-
3
結果をコピーまたは入れ替え右側の結果をコピーするか、⇄ ボタンで入出力を入れ替えて逆方向の変換を行います。
❓ よくある質問
HTML エスケープと URL エンコードの違いは何ですか?
日本語などの非 ASCII 文字もエスケープできますか?
SQL インジェクション対策としてこのツールは使えますか?
🐛 このツールで問題が発生しましたか?
完全無料・登録不要。再現手順だけでも結構です。届いたご報告は運営者に直接届き、修正の参考にします。
ご報告ありがとうございます!
運営者に届きました。改善の参考にさせていただきます。