文字列エスケープとは?
文字列エスケープとは、文字列リテラル内で特別な意味を持つ文字の前にバックスラッシュ(またはその他のマーカー)を挿入するプロセスです。プログラミング言語のパーサーがダブルクォートで囲まれた文字列内でダブルクォートを検出すると、それを文字列の終端として解釈します。バックスラッシュでクォートをエスケープする — "の代わりに\"と記述する — ことで、パーサーはそれをデリミタではなくリテラル文字として扱います。文字列リテラルを使用するすべての言語にはエスケープルールがありますが、正確なシーケンスは言語によって異なります。
最も一般的なエスケープシーケンスは、ソースコードに直接記述できない空白文字や制御文字に対応しています。改行は\n、タブは\t、リテラルのバックスラッシュは\\になります。これらの規約はC言語(ISO/IEC 9899)に遡り、JavaScript(ECMA-262)、Python、Java、Go、Rustに採用されています。JSON(RFC 8259)は同じ構文を使用しますが、サポートするシーケンスのセットはより小さくなっています。
アンエスケープ(「デエスケープ」とも呼ばれます)は逆の操作で、エスケープシーケンスを元の文字に変換します。これはログファイルの読み取り、APIレスポンスの解析、二重エスケープされたデータのデバッグ時によく行われます。どちらの操作も機械的なものですが、手作業では間違いが起きやすいため、複数行の文字列、埋め込みクォート、またはUnicode文字を扱う際に開発者がエスケープ・アンエスケープツールを使用する理由です。
オンライン文字列エスケープツールを使う理由
バックスラッシュを手動で追加・削除する作業は面倒で、特にネストされたクォートや複数行の入力では間違いが起きやすいです。ブラウザベースの文字列エスケープツールは、REPLをセットアップしたり使い捨てスクリプトを書いたりすることなく、即座に結果を提供します。
文字列エスケープのユースケース
エスケープシーケンスリファレンス
以下の表は一般的なエスケープシーケンスと、JavaScript、Python、JSONでのサポート状況を示しています。3つの言語はコアセット(改行、タブ、バックスラッシュ、ダブルクォート)を共有していますが、シングルクォート、16進数エスケープ、拡張Unicode表記については異なります。
| シーケンス | 意味 | JavaScript | Python | JSON |
|---|---|---|---|---|
| \n | Newline (LF) | Yes | Yes | Yes |
| \r | Carriage return | Yes | Yes | Yes |
| \t | Tab | Yes | Yes | Yes |
| \\ | Backslash | Yes | Yes | Yes |
| \" | Double quote | Yes | Yes | Yes |
| \' | Single quote | Yes | Yes | No |
| \b | Backspace | Yes | Yes | Yes |
| \f | Form feed | Yes | Yes | Yes |
| \v | Vertical tab | Yes | Yes | No |
| \0 | Null character | Yes | Yes | No |
| \xNN | Hex byte | Yes | Yes | No |
| \uNNNN | Unicode (BMP) | Yes | Yes | Yes |
| \u{N..} | Unicode (full) | Yes | No | No |
JavaScript vs Python vs JSONのエスケープ比較
これら3つのフォーマットは同じバックスラッシュベースの構文を共有していますが、有効なシーケンスやエッジケースの処理方法が異なります。間違ったモードを選択すると、見た目は正しいが解析時に失敗する出力が生成されます。
コード例
JavaScript、Python、Go、およびコマンドラインでの文字列のエスケープ・アンエスケープの例です。
// Escape a string with special characters
const raw = 'Line 1\nLine 2\tTabbed "quoted"';
const escaped = JSON.stringify(raw);
// → '"Line 1\\nLine 2\\tTabbed \\"quoted\\""'
// Unescape a JSON string value
const input = '"Hello\\nWorld"';
const unescaped = JSON.parse(input);
// → "Hello\nWorld" (actual newline character)
// Template literals don't need quote escaping
const tpl = `She said "hello"`;
// → 'She said "hello"' — no backslashes needed
// Escape for use inside a RegExp
const query = 'price: $5.00 (USD)';
const safe = query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// → "price: \\$5\\.00 \\(USD\\)"# Escape with repr() — shows escape sequences
raw = "Line 1\nLine 2\t'quoted'"
print(repr(raw))
# → "Line 1\nLine 2\t'quoted'"
# Raw strings skip escape processing
path = r"C:\Users\name\Documents"
print(path)
# → C:\Users\name\Documents (backslashes kept literal)
# JSON escaping with json module
import json
data = 'He said "hello\nworld"'
escaped = json.dumps(data)
# → '"He said \\"hello\\nworld\\""'
# Unicode escaping
text = "Caf\u00e9" # → "Café"
print(text.encode('unicode_escape').decode())
# → "Caf\\xe9"package main
import (
"fmt"
"strconv"
"encoding/json"
)
func main() {
// strconv.Quote adds escape sequences and wraps in quotes
raw := "Line 1\nLine 2\t\"quoted\""
fmt.Println(strconv.Quote(raw))
// → "\"Line 1\\nLine 2\\t\\\"quoted\\\"\""
// strconv.Unquote reverses it
unescaped, _ := strconv.Unquote(`"hello\nworld"`)
fmt.Println(unescaped)
// → hello
// world
// JSON marshal handles escaping automatically
b, _ := json.Marshal("tabs\there & \"quotes\"")
fmt.Println(string(b))
// → "tabs\there \u0026 \"quotes\""
}# Use $'...' syntax for escape sequences in bash echo $'Line 1\nLine 2\tTabbed' # → Line 1 # Line 2 Tabbed # printf interprets escape sequences printf 'Path: C:\\Users\\name\n' # → Path: C:\Users\name # Use jq to escape a string for JSON echo 'He said "hello"' | jq -Rs . # → "He said \"hello\"\n" # Unescape JSON string with jq echo '"Line 1\\nLine 2"' | jq -r . # → Line 1 # Line 2