- 技術 💻
ダブルクォーテーションとシングルクォーテーションの違い|10言語で実行
結論
ダブルクォーテーション(")とシングルクォーテーション(')は、どちらも文字列を囲む記号ですが、bash・PHP・Ruby では「中の変数を展開するか」、JSON・SQL・Java・C では「使える場所そのもの」が違います。Python と JavaScript では、どちらで囲んでも同じ文字列です。
この記事でわかること
- bash・Python・PHP・SQL など10言語で動かした出力の違い
- 全角の“”を貼ったときのエラー原文と、見つけて直す方法
- Windows・Mac・スマホでの入力方法と、場面別の判断表
同じ「引用符」でも、書く場所によって意味が変わります。まず、記号で意味が変わるかどうかで大きく3つに分かれます。
flowchart TD
S{記号で意味が<br>変わるか} -->|いいえ| N[Python・JS<br>どちらも同じ]
S -->|はい| T{何が<br>変わるか}
T -->|展開| E[bash・PHP・Ruby<br>ダブルだけ展開]
T -->|型・役割| R[JSON・SQL・C<br>入れ替えでエラー]
よく調べられることの答えを先にまとめます。
| 知りたいこと | 答え | 詳しい節 |
|---|---|---|
| ダブルクォーテーションとは | 「"」の記号。日本語では二重引用符。文字列や引用を囲む | ダブルクォーテーションとは |
| シングルクォーテーションとの違い(プログラミング) | bash・PHP・Ruby はダブルだけ変数を展開。Python・JS は同じ | 場面別の意味の表 |
| シェルでの違い | シングルは全部そのまま。ダブルは $・`・\ だけ働く | bash の違い |
| JSON でシングルが使えない | JSON の規格は「"」だけ。' はエラーになる | JSON の違い |
| SQL で column does not exist | SQL は値が「'」、列名が「"」。値を " で囲んだ | SQL の違い |
| 全角の“”でエラー | コピーで向きのある引用符が混ざった。半角に置き換える | 全角・スマート引用符のエラー |
| キーボードでの打ち方 | 日本語配列は Shift+2(")・Shift+7(')。英語配列は Enter の左 | 入力方法 |
| どちらを使うか迷う | 決まりがある場所は決まりに従い、無ければチームで統一 | 判断表 |
確認環境:Ubuntu 24.04.5 LTS の上で、bash 5.2.21・dash 0.5.12、Python 3.13.18(json・csv・sqlite3・PyYAML 6.0.3)、Node.js 22.23.4、PHP 8.3.6、Ruby 3.3.6、OpenJDK 21.0.12.1、Go 1.24.7、rustc 1.97.0、gcc 13.3.0 で同じ文字列を書き、出力とエラーの原文を確かめました。SQL は PostgreSQL 16.15 を作業用のフォルダーに作った自分のクラスターとして 127.0.0.1 で起動し(終わったあとに削除)、SQLite 3.45.1 は Python の sqlite3 で動かしました。JSON は jq 1.7、HTML の属性は Chromium 153.0.8010.12(playwright 1.63.0)で読み込んで、属性の値を DOM から取り出しています。全角記号の検出は GNU grep 3.11・sed 4.9 です。Windows・Mac・iPhone の設定と入力は手元で動かせないため、Apple サポート・Microsoft サポート・Microsoft Learn・Google 検索ヘルプの公式ページで確かめた範囲だけを書きました。MySQL の挙動は MySQL 8.4 リファレンスマニュアルで確かめています。図は mermaid 11.16.0 で描画を確かめました(確認日 2026年10月29日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ダブルクォーテーションとシングルクォーテーションの違い|10言語で実行」
ダブルクォーテーションとは(記号・呼び方・全角と半角)
この節では、ダブルクォーテーションとシングルクォーテーションがどの記号を指すのか、似た記号とどう違うのかが分かります。
ダブルクォーテーション(double quotation mark)は「"」、シングルクォーテーション(single quotation mark)は「'」の記号です。 日本語では二重引用符・一重引用符と呼びます。「ダブルクォート」「ダブルコーテーション」「ダブルクオーテーション」も同じ記号を指す呼び方で、プログラミングの文書では「ダブルクォート」「シングルクォート」と短く書くことが多いです。
キーボードから入る半角の「"」「'」は、上下や左右の向きが無いまっすぐな記号です。一方、文書ソフトや本で使う「“ ”」「‘ ’」は、開きと閉じで向きが違う別の文字です。コンピューターの中では、どちらも別の番号(文字コード)を持っています。Python の unicodedata で調べた結果です。
| 記号 | Unicode | 名前(Unicode) | UTF-8 のバイト | 主な使い道 |
|---|---|---|---|---|
| " | U+0022 | QUOTATION MARK | 22 | プログラムの文字列・JSON・CSV |
| ' | U+0027 | APOSTROPHE | 27 | プログラムの文字列・SQL の値 |
| ` | U+0060 | GRAVE ACCENT | 60 | バッククォート。JS のテンプレート・MySQL の名前 |
| “ ” | U+201C・U+201D | LEFT/RIGHT DOUBLE QUOTATION MARK | e2 80 9c・e2 80 9d | 文章の引用(英文・日本語の文書) |
| ‘ ’ | U+2018・U+2019 | LEFT/RIGHT SINGLE QUOTATION MARK | e2 80 98・e2 80 99 | 文章の引用・英文のアポストロフィ |
| " ' | U+FF02・U+FF07 | FULLWIDTH QUOTATION MARK など | ef bc 82・ef bc 87 | 全角の文字としての記号 |
| 〝 〟 | U+301D・U+301F | REVERSED DOUBLE PRIME QUOTATION MARK など(ダブルミニュート) | e3 80 9d・e3 80 9f | 日本語の縦書きの強調・引用 |
- 半角の「'」は、Unicode の名前が APOSTROPHE(アポストロフィ)です。 英語の it's の「'」と、シングルクォーテーションは、半角では同じ1つの文字を兼ねています。
- 「“」「”」は、Unicode で東アジアの幅が「A(どちらとも決まらない)」に分類されています。日本語のフォントでは全角の幅で表示されることが多いため、「全角のダブルクォーテーション」と呼ばれることがあります。
- キーボードの「"」は1種類しかありません。ASCII(半角英数の文字の表)には向きの無い「"」「'」しか入っていないため、プログラムの文字列は開きと閉じに同じ記号を使います。
文章での使い方(日本語・英語)
プログラム以外の文章では、引用・会話・作品名・強調に使います。厳密な決まりは無く、文書の中で揃えることが大切です。
- 日本語の文章:引用や会話には、ふつうは「」(かぎかっこ)と『』(二重かぎかっこ)を使います。“ ”は、強調や英語の語句、別の意味で使う言葉を示すときに使われます。開き「“」と閉じ「”」を逆にしない、必ず対で使う、1つの文書の中で「」と“ ”の役割を混ぜない、の3点に気をつけます。
- 英語の文章:引用・会話・作品の題名・皮肉(いわゆる、という含み)に使います。アメリカ英語ではダブルクォーテーションが基本で、引用の中の引用にシングルを使います。イギリス英語ではシングルを外側に使う書き方も広く使われます。
- ピリオドとカンマの位置:アメリカ英語では閉じる引用符の前("word.")に、イギリス英語では文の構造に合わせて外("word".)に置くことが多い、という慣習の違いがあります。
場面別の意味の表(言語・シェル・JSON・CSV・SQL・HTML)
この節では、ダブルクォーテーションとシングルクォーテーションの意味が、書く場所ごとにどう違うのかが一覧で分かります。
「どちらで囲んでも同じ」なのは Python・JavaScript・HTML の属性などに限られます。 手元で実際に動かした結果をまとめました。
| 書く場所 | ダブル(") | シングル(') | 入れ替えると |
|---|---|---|---|
| bash・sh(シェル) | $変数・$(コマンド)・\ が働く | 中身を全部そのまま渡す | 展開される・されないが変わる |
| PHP・Ruby・Perl | 変数を展開し、\n などのエスケープも働く | ほぼ書いたまま(\' と \\ だけ) | 展開される・されないが変わる |
| PowerShell | $変数を展開。エスケープは ` | 書いたまま。' は '' と書く | 展開される・されないが変わる(公式) |
| Python・JavaScript・TypeScript | 文字列 | 同じ文字列 | 変わらない |
| Java・C・C++・Go・Rust | 文字列 | 1文字(char・rune) | 型が変わる・コンパイルエラー |
| JSON | 文字列とキーはこれだけ | 使えない | 構文エラー |
| SQL(標準・PostgreSQL) | 列名・表名などの名前 | 文字列の値 | 「列が無い」エラー |
| CSV(RFC 4180) | カンマ・改行を含む値を囲む | ただの文字 | 値が途中で分かれる |
| YAML | \n などのエスケープが働く | 書いたまま。' は '' と書く | \t などの意味が変わる |
| HTML の属性 | 値を囲む | 値を囲む(同じ) | 変わらない。中に同じ記号は不可 |
1展開の違い
bash・PHP・Ruby・PowerShell。ダブルは中の変数を値に置き換え、シングルは置き換えない。
2型・役割の違い
Java・C・Go・Rust はシングルが1文字。SQL はシングルが値でダブルが名前。JSON はダブルしか無い。
3違いが無い
Python・JavaScript・HTML の属性。中に入れたい記号と逆のほうで囲むと、エスケープが要らない。
bash(シェル)のダブルクォーテーションとシングルクォーテーションの違い
この節では、Linux や Mac のターミナル(bash・zsh・sh)で、2つの引用符がどう違うのかが実行結果で分かります。
シングルクォーテーションの中は、すべての文字が書いたまま渡ります。ダブルクォーテーションの中では、$(変数・コマンド置換)、`(バッククォート)、\(一部のエスケープ)だけが働きます。 bash の公式マニュアル(Quoting)の定義どおりの結果になりました。
name=RJC
echo "1: Hello $name"
echo '2: Hello $name'
echo "3: today is $(date +%Y)"
echo '4: today is $(date +%Y)'
echo "5: tab\there"
echo '6: tab\there'
echo $'7: tab\there'
echo "8: it's ok"
echo '9: say "hi"'
echo '10: it'\''s'
echo "11: \"quoted\" and \$name"
1: Hello RJC
2: Hello $name
3: today is 2026
4: today is $(date +%Y)
5: tab\there
6: tab\there
7: tab here
8: it's ok
9: say "hi"
10: it's
11: "quoted" and $name
- 1と2:ダブルは
$nameを値(RJC)に置き換え、シングルは$nameの文字のまま。 - 5と6:bash の
echoは、ダブルでもシングルでも\tをタブにしませんでした。タブにしたのは$'...'(7)だけです。 - 10:シングルの中にシングルは書けません(\ を付けても不可)。いったん閉じて
\'を挟み、また開く'it'\''s'の形にします。 - 11:ダブルの中のダブルは
\"、展開したくない $ は\$と書きます。
同じ \t でも echo の種類で結果が変わる
Ubuntu の /bin/sh(dash)で同じことをすると、ダブルの中の \t がタブになりました。
$ cat d.sh
echo $'a\tb'
echo "x\ty"
$ dash d.sh
$a b
x y
dash では $'...' が使えず、先頭の $ がそのまま出ています。一方、ダブルの中の \t は、dash の echo がタブに変えました。エスケープを解釈しているのは引用符ではなく echo のほうです。 シェルによらず同じ結果にしたいときは printf 'a\tb\n' を使います。
空白を含むファイル名と変数は、ダブルで囲む
$ f="my file.txt"; touch "$f"
$ ls $f
ls: cannot access 'my': No such file or directory
ls: cannot access 'file.txt': No such file or directory
$ ls "$f"
my file.txt
$ set -- 'a b' c
$ for a in "$@"; do echo "[$a]"; done
[a b]
[c]
$ for a in $*; do echo "<$a>"; done
<a>
<b>
<c>
変数を囲まずに使う
ls $f・rm $dir/*。空白で2つに分かれ、別のファイルを指すことがあるls "$f"・rm "$dir"/*。変数はダブルで囲み、値をひとかたまりで渡す展開はしたいが、分けたくない。だからシェルの変数はダブルで囲む
JSON をコマンドに渡すときは、外をシングルにする
API に JSON を送るときによく詰まる形です。受け取った引数をそのまま json.loads に渡すスクリプトで確かめました(id=7)。
$ python3 args.py '{"id": $id}'
'{"id": $id}' -> JSONDecodeError Expecting value: line 1 column 8 (char 7)
$ python3 args.py "{"id": $id}"
'{id: 7}' -> JSONDecodeError Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
$ python3 args.py "{\"id\": $id}"
'{"id": 7}' -> JSON OK {'id': 7}
$ python3 args.py '{"id": '"$id"'}'
'{"id": 7}' -> JSON OK {'id': 7}
外をダブルにすると、中の " がシェルに取られて消え、{id: 7} になりました。外をシングルにすると中の " は残りますが、$id も展開されません。変数を入れたいときは、3つ目(中の " を \" にする)か、4つ目(シングルを閉じてダブルで変数だけ囲む)の形にします。変数の展開の種類は、関連記事「bash変数展開の一覧|${var:-default}と文字列の置換・切り出し」で扱っています。
PowerShell は bash と同じ考え方(公式)
Windows の PowerShell も、ダブルが展開あり・シングルが展開なしです。Microsoft Learn の about_Quoting_Rules は「二重引用符で囲まれた文字列は、展開可能な文字列です」と書いています。違いは、エスケープの記号が \ ではなく `(バッククォート)である点と、シングルの中のシングルを ''(2つ重ねる)で書ける点です。
$i = 5
"The value of $i is $i." # The value of 5 is 5.
'The value of $i is $i.' # The value of $i is $i.
"The value of `$i is $i." # The value of $i is 5.
'don''t' # don't
Pythonのダブルクォーテーションとシングルクォーテーション
この節では、Python で2つの引用符に違いがあるのか、どちらを選べばよいのかが分かります。
Python では、'abc' と "abc" はまったく同じ文字列です。 変数の埋め込みは引用符の種類ではなく、先頭の f(f-string)で決まります。
name = "RJC"
print('abc' == "abc")
print('Hello {name}', "Hello {name}", f'Hello {name}', f"Hello {name}")
print('tab\there', "tab\there", r'tab\there')
print("it's", 'say "hi"', 'it\'s', "say \"hi\"")
print(repr("it's"), repr('say "hi"'), repr('both \' and "'))
print("""triple "double" and 'single'""")
True
Hello {name} Hello {name} Hello RJC Hello RJC
tab here tab here tab\there
it's say "hi" it's say "hi"
"it's" 'say "hi"' 'both \' and "'
triple "double" and 'single'
\tはどちらの引用符でもタブになり、rを付けた raw 文字列だけが書いたまま残りました。repr()の表示は、中にシングルがあればダブルで、無ければシングルで囲まれます。表示の引用符は Python が選んでいるだけで、値には含まれません。- 三重引用符(
"""・''')の中には、どちらの引用符もエスケープなしで書けます。
どちらを使うか(PEP 8・Black)
Python の公式のスタイルガイド PEP 8 は「シングルクォートの文字列とダブルクォートの文字列は同じ」で、どちらかを勧めることはしない、決めた規則を守る、と書いています。文字列の中に引用符を含むときは、エスケープを避けるため逆のほうを使う、三重引用符はダブルを使う、ともあります。整形ツールの Black はダブルに揃えます(エスケープが増える場合はシングルのまま)。チームで Black を使っているなら、ダブルにしておくと差分が出ません。f-string の書式の全項目は、関連記事「Python f-string書式指定|全項目の早見表と実行結果(3.14対応)」で扱っています。
print した辞書は JSON ではない
import json
d = {'name': 'RJC', 'q': 'it\'s'}
print(str(d))
print(json.dumps(d, ensure_ascii=False))
{'name': 'RJC', 'q': "it's"}
{"name": "RJC", "q": "it's"}
print(d) の表示はシングルで囲まれた Python の表記で、JSON ではありません。ファイルや API に渡すときは json.dumps を通します。逆に、シングルで書かれた文字列を辞書に戻すときは、json.loads ではなく ast.literal_eval が読みます(手元で {'a': 1} を読めました)。
JavaScriptのシングル・ダブル・バッククォート(テンプレートリテラル)
この節では、JavaScript・TypeScript の3種類の引用符の違いと、整形ツールの既定が分かります。
JavaScript の 'abc' と "abc" は同じで、変数を埋め込めるのはバッククォート(`)のテンプレートリテラルだけです。 Node.js 22.23.4 で実行しました。
const name = "RJC";
console.log('abc' === "abc");
console.log('Hello ${name}', "Hello ${name}", `Hello ${name}`);
console.log('tab\there' === "tab\there");
console.log(JSON.stringify({ q: "it's", d: 'say "hi"' }));
true
Hello ${name} Hello ${name} Hello RJC
true
{"q":"it's","d":"say \"hi\""}
シングルでもダブルでも ${name} は文字のまま出ました。JSON.stringify は、元の引用符にかかわらず JSON の決まりどおりダブルで出力し、中の " を \" にしています。
整形ツールの Prettier は、singleQuote の既定が false(ダブルを使う)です。公式ドキュメントによると、文字列の中に引用符が多いときは、少ないほうの引用符で囲みます。JSX の属性は別の設定(jsxSingleQuote、既定は false)で決まります。テンプレートリテラルの書き方は、関連記事「JavaScriptテンプレートリテラルの使い方|変数埋め込み・複数行」で扱っています。
PHP・Rubyのダブルクォーテーションは変数を展開する
この節では、PHP と Ruby で2つの引用符の結果がどう変わるのかと、「シングルのほうが速い」は本当かが、実行と計測で分かります。
PHP と Ruby は、ダブルの中の変数を展開し、\n などのエスケープも解釈します。シングルの中はほぼ書いたままです。
<?php
$name = "RJC";
var_dump('abc' === "abc");
echo 'Hello $name', " / ", "Hello $name", " / ", "Hello {$name}san", "\n";
echo 'tab\there', " / ", "tab\there", "\n";
echo 'it\'s \n', " / ", "say \"hi\"", "\n";
echo <<<EOT
heredoc: $name
EOT;
echo "\n";
echo <<<'EOT'
nowdoc: $name
EOT;
bool(true)
Hello $name / Hello RJC / Hello RJCsan
tab\there / tab here
it's \n / say "hi"
heredoc: RJC
nowdoc: $name
PHP 8.3.6 の出力です。ヒアドキュメント(<<<EOT)はダブルと同じく展開し、Nowdoc(<<<'EOT')はシングルと同じく展開しません。"Hello {$name}san" のように、変数のすぐ後ろに文字が続くときは {} で区切ります。シングルの中で働くエスケープは \' と \\ だけで、'\n' は2文字のまま出ました。
Ruby 3.3.6 も同じ考え方で、展開の書き方が #{} です。
name = "RJC"
puts 'Hello #{name}', "Hello #{name}"
p 'tab\there', "tab\there"
Hello #{name}
Hello RJC
"tab\\there"
"tab\there"
「PHP はシングルのほうが速い」を計測した
同じ文字列を 2,000万回代入する時間を、OPcache を切った CLI で3回ずつ測りました。
| 回 | 'hello world' | "hello world" | "hello $i" | 'hello ' . $i |
|---|---|---|---|---|
| 1回目 | 110 ms | 87 ms | 1,054 ms | 903 ms |
| 2回目 | 89 ms | 91 ms | 1,036 ms | 1,373 ms |
| 3回目 | 151 ms | 133 ms | 1,001 ms | 979 ms |
変数の無い文字列では、回ごとのばらつきのほうが大きく、どちらが速いとは言えませんでした。OPcache のデバッグ出力で命令を見ると、どちらも同じ1行になっていました。
$ php -d opcache.enable_cli=1 -d opcache.opt_debug_level=0x10000 op.php
0000 ASSIGN CV0($a) string("hello")
0001 ASSIGN CV1($b) string("hello")
0002 RETURN int(1)
変数を含まない "hello" は、読み込みの時点でシングルと同じ定数の文字列になります(トークンはどちらも T_CONSTANT_ENCAPSED_STRING でした)。速さで選ぶ理由は無く、「展開したいか」で選びます。
Java・C・Go・Rustではシングルが1文字、ダブルが文字列
この節では、型のある言語で2つの引用符を取り違えたときのエラーと、その読み方が分かります。
Java・C・C++・Go・Rust では、シングルクォーテーションは1文字(char・rune)、ダブルクォーテーションは文字列で、別の型です。 シングルで2文字以上を囲むとコンパイルエラーになります。
char c = 'A'; String s = "A";
System.out.println(c + 1); // 66('A' は数値の 65 として足される)
System.out.println(s + 1); // A1(文字列の連結)
OpenJDK 21 で実行すると、c + 1 は 66、s + 1 は A1 でした。同じ「A」でも、シングルは文字コードの数値として計算されます。シングルで文字列を書いたときの javac のエラーです。
jv/Bad.java:1: error: unclosed character literal
public class Bad { public static void main(String[] a) { char c = 'AB'; String s = 'hello'; } }
^
jv/Bad.java:1: error: not a statement
...
6 errors
| 言語 | 'A' の型 | シングルで 'hello' と書いたとき(原文) |
|---|---|---|
| Java 21 | char | error: unclosed character literal |
| Go 1.24 | rune(int32・値は 65) | more than one character in rune literal |
| Rust 1.97 | char | error: character literal may only contain one codepoint |
| C(gcc 13) | int(sizeof は 4) | warning: multi-character character constant(エラーにならず 'AB' は 16706) |
Rust のコンパイラーは、ダブルに直す案まで出しました。
error: character literal may only contain one codepoint
--> b.rs:1:21
|
1 | fn main() { let s = 'hello'; }
| ^^^^^^^
|
help: if you meant to write a string literal, use double quotes
|
1 - fn main() { let s = 'hello'; }
1 + fn main() { let s = "hello"; }
- C は警告だけで通ってしまいます。
'AB'は2文字を1つの整数(16706)にした値になり、sizeof('A')は 4、sizeof("A")は終端の \0 を含めて 2 でした。 - Go のバッククォート(
`C:\new\table "raw"`)は raw 文字列で、\ も " もそのまま入りました。Java の複数行の文字列はテキストブロック(""")で書け、中の " と ' はエスケープ不要でした。
JSONでシングルクォーテーションが使えない理由とエラー
この節では、JSON で引用符がどう決まっているのかと、シングルや全角を使ったときのエラーの原文が分かります。
JSON の規格(RFC 8259)では、文字列は「"」で始まり「"」で終わります。キーも文字列なので、シングルや全角の“”は使えません。 JavaScript のオブジェクトの書き方とは違うので、手で書いた JSON でよくつまずきます。
Python 3.13 json.loads("{'a': 1}")
json.decoder.JSONDecodeError: Expecting property name enclosed in double quotes: line 1 column 2 (char 1)
Node.js 22 JSON.parse("{'a': 1}")
SyntaxError: Expected property name or '}' in JSON at position 1 (line 1 column 2)
jq 1.7 echo "{'a': 1}" | jq .
jq: parse error: Invalid numeric literal at line 1, column 5
全角の {“a”: 1} でも、Python と Node.js は同じ文言、jq は「Invalid numeric literal at line 1, column 9」でした。jq の「Invalid numeric literal」は、引用符で囲まれていない文字を数値として読もうとして失敗した、という意味です。 数値の話に見えても、原因は引用符です。
| 書いた JSON | 結果 | 直し方 |
|---|---|---|
{'a': 1} |
エラー(property name) | {"a": 1} |
{“a”: 1} |
エラー(同じ文言) | 全角を半角の " に |
{"a": "x(タブ)y"} |
Invalid control character | タブは \t と書く |
{"q": "it's"} |
OK | ' は JSON の中でただの文字 |
{"d": "say \"hi\""} |
OK | 中の " は \" |
JSON の読み書きのエラーと整形は、関連記事「JSON.parseとJSON.stringifyの使い方|エラー原因と整形」で扱っています。
SQLのシングルクォーテーションとダブルクォーテーション(PostgreSQL・MySQL・SQLite)
この節では、SQL で値と名前をどちらの引用符で囲むのかと、データベースごとの違い、エラーの原文が分かります。
標準の SQL では、シングルクォーテーションは文字列の値、ダブルクォーテーションは列名・表名などの名前(識別子)を囲みます。 値をダブルで囲むと、データベースは「その名前の列」を探します。PostgreSQL 16.15 で確かめました。
CREATE TABLE users (id int, name text, "Order" int);
INSERT INTO users VALUES (1, 'O''Brien', 3);
SELECT name FROM users WHERE name = 'O''Brien'; -- O'Brien
SELECT * FROM users WHERE name = "RJC";
SELECT Order FROM users;
SELECT "order" FROM users;
SELECT name AS '表示名' FROM users;
ERROR: column "RJC" does not exist
LINE 1: SELECT * FROM users WHERE name = "RJC";
^
ERROR: syntax error at or near "FROM"
LINE 1: SELECT Order FROM users;
^
ERROR: column "order" does not exist
LINE 1: SELECT "order" FROM users;
^
HINT: Perhaps you meant to reference the column "users.Order".
ERROR: syntax error at or near "'表示名'"
LINE 1: SELECT name AS '表示名' FROM users;
^
- column "RJC" does not exist:値の RJC をダブルで囲んだため、列名として探された。
'RJC'に直すと動く。 - Order(予約語):囲まないと構文エラー。ダブルで囲んだ名前は大文字・小文字も区別され、
"order"では見つからなかった。 - 別名(AS):別名も名前なので
AS "表示名"と書く。シングルは構文エラーになった。 - 値の中のシングル:
'O''Brien'のように2つ重ねる。PostgreSQL の標準の文字列では\tは2文字のままで、E'tab\tx'(E 付き)にするとタブになった。ドル記号2つで囲むドル引用符では、' も " もそのまま書けた。
データベースごとの違い
| データベース | '…' | "…" | 名前を囲む記号 |
|---|---|---|---|
| PostgreSQL 16 | 値 | 名前(無ければエラー) | " |
| MySQL 8.4(既定) | 値 | 値としても使える | `(バッククォート) |
| MySQL(ANSI_QUOTES) | 値 | 名前 | " と ` |
| SQLite 3.45 | 値 | 名前。無ければ値として読む | " |
MySQL 8.4 のリファレンスマニュアルは、文字列をシングルかダブルで囲める一方、ANSI_QUOTES の SQL モードではダブルが識別子として扱われるため、文字列はシングルだけになる、と書いています。どのデータベースでも通る書き方は「値はシングル」です。
SQLite は、間違いがエラーにならないので気づきにくい動きをします。Python の sqlite3 で実行した結果です。
SELECT * FROM users WHERE name = 'RJC' -> [(1, 'RJC')]
SELECT * FROM users WHERE name = "RJC" -> [(1, 'RJC')]
SELECT * FROM users WHERE name = "name" -> [(1, 'RJC')]
SELECT "nothing" FROM users -> [('nothing',)]
"RJC" は RJC という列が無いので値として読まれ、結果が出ました。ところが "name" は name 列として読まれ、「name 列 = name 列」で全行が当たりました。"nothing" は、無い列名がエラーにならず文字列として返っています。SQLite の公式ドキュメント(Quirks)は、これを「誤った機能(misfeature)」と呼び、綴りを間違えたダブルの識別子がエラーにならず文字列として読まれると説明しています。コンパイル時の -DSQLITE_DQS=0 か、接続ごとの sqlite3_db_config で止められ、3.41.0 以降のコマンドラインのシェルでは既定で無効です。
値は引用符で組み立てず、プレースホルダーで渡す
name = "O'Brien"
c.execute("INSERT INTO users VALUES (2, ?)", (name,)) # OK
c.execute(f"SELECT * FROM users WHERE name = '{name}'") # NG
[("O'Brien",)]
f-string -> OperationalError near "Brien": syntax error
値に ' が入っていると、自分で囲んだ引用符がそこで閉じてしまい、構文エラーになりました。文字列を組み立てて SQL を作ると、入力しだいで SQL の意味が変わります。 値は ? などのプレースホルダーで渡し、引用符の付け方はドライバーに任せます。LIKE の % と _ の扱いは、関連記事「SQL LIKE部分一致とエスケープ|%・_の扱いをDB別にコピペ解説」で扱っています。
CSV・YAML・HTMLでのダブルクォーテーション
この節では、データのファイル(CSV・YAML)と HTML の属性で、引用符がどう扱われるのかが分かります。
CSV:囲むのはダブルだけ、中の " は "" にする
CSV の規格(RFC 4180)で値を囲めるのはダブルクォーテーションだけで、中の " は "" と2つ重ねます。 Python の csv で書き出した結果です。
id,name,memo
1,"RJC, Inc.","say ""hi"""
2,O'Brien,"line1
line2"
カンマ・改行・" を含む値だけがダブルで囲まれ、O'Brien の ' はそのままでした。読み込みでは、シングルや全角で囲んだ値はカンマで分かれました。
3 ['1', 'RJC, Inc.', 'say "hi"']
4 ['2', "'RJC", " Inc.'", 'x']
4 ['3', '“RJC', ' Inc.”', 'x']
1行目は3列、シングルと全角の行は4列になりました。CSV で列がずれるときは、値を囲んでいる記号が半角の " かを確かめます。
YAML:シングルは書いたまま、ダブルはエスケープが働く
plain: it's ok
single: 'tab\tno ''escape'''
double: "tab\tyes \"escape\""
num_str: "010"
num: 010
bool_str: "yes"
bool: yes
{'plain': "it's ok", 'single': "tab\\tno 'escape'", 'double': 'tab\tyes "escape"', 'num_str': '010', 'num': 8, 'bool_str': 'yes', 'bool': True}
PyYAML 6.0.3 では、シングルの \t は2文字のまま、ダブルはタブになりました。シングルの中の ' は '' と書きます。囲まない 010 は 8(8進数)、yes は True になりました(PyYAML は YAML 1.1 の規則で読みます)。文字列として残したい値は、どちらかの引用符で囲みます。
HTML の属性:どちらで囲んでも同じ
Chromium で読み込み、属性の値を DOM から取り出した結果です。
| 書いた属性 | Chromium が読んだ値 |
|---|---|
title="double" |
title=[double] |
title='single' |
title=[single] |
title="say "hi" there" |
title=[say ] と、余分な属性 hi" と there" |
title="say "hi" there" |
title=[say "hi" there] |
title='say "hi" there' |
title=[say "hi" there] |
href=“https://example.com/” |
“ ” ごと値になり、同じフォルダーの「%E2%80%9Chttps://…」へのリンクになった |
class=x y(囲まない) |
class=[x] と、別の属性 y |
属性の中に同じ記号を入れると、そこで値が終わります。" と書くか、外側を逆の記号にします。全角の“”で囲んだ href は、エラーは出ずに、壊れたリンクになりました。 Python の html.escape() は、既定で " を "、' を ' に変えました。
全角・スマート引用符(“”)を貼ったときのエラー原文と直し方
この節では、Word・メール・チャット・Web ページからコピーしたコマンドやコードが動かないときに、原因の引用符を見つけて直す方法が分かります。
文書ソフトやチャットは、入力した " を自動で “ ” に変えることがあります(スマート引用符)。 見た目は似ていても別の文字なので、プログラムは引用符として扱いません。同じ1行を全角の“”で書いて実行した結果です。
| 言語 | 書いたもの | エラー(原文) |
|---|---|---|
| Python 3.13 | print(“Hello”) |
SyntaxError: invalid character '“' (U+201C) |
| Python 3.13 | print("Hello") |
SyntaxError: invalid character '"' (U+FF02) |
| Node.js 22 | console.log(“Hello”); |
SyntaxError: Invalid or unexpected token |
| PHP 8.3 | echo “Hello”; |
Uncaught Error: Undefined constant "“Hello”" |
| Ruby 3.3 | puts “Hello” |
undefined local variable or method `“Hello”' for main (NameError) |
| bash 5.2 | ls “my file.txt” |
ls: cannot access '“my': No such file or directory |
| jq 1.7 | {“a”: 1} |
jq: parse error: Invalid numeric literal |
Python だけが文字の番号(U+201C)まで出しました。PHP と Ruby は「“Hello”」を1つの名前(定数・変数)と読み、bash は “ を名前の一部として渡しています。bash の echo “Hello $name” はエラーにならず「“Hello RJC”」と表示されるため、気づくのが遅れます。
症状→原因→直し方
| 症状 | 原因 | 直し方 |
|---|---|---|
| コピーしたコマンドだけ動かない | “ ” ‘ ’ が混ざった | 下の grep で探し、sed で半角に置き換える |
| invalid character '“' (U+201C) | Python のコードに全角の引用符 | エディターで “ を検索して " にする |
| unterminated string literal | 中の ' で文字列が閉じた・閉じ忘れ | 外を逆の記号にする・\' にする |
| unexpected EOF while looking for matching | bash で引用符が閉じていない | エラーに出た記号(` " ' のどれか)の対を探す |
| column "…" does not exist | SQL の値をダブルで囲んだ | 値はシングルにする |
| Expecting property name enclosed in double quotes | JSON にシングル・全角 | キーと文字列を半角の " にする |
| CSV の列が1つずれる | 値をシングル・全角で囲んだ | 半角の " で囲み、中の " は "" |
| Mac・iPhone で打つと “ になる | スマート引用符の設定が有効 | 次の節の設定で無効にする |
まぎれ込んだ引用符を見つけて直す(Linux・Mac・Git Bash)
# 見つける(行番号つき)
grep -nP '[\x{201C}\x{201D}\x{2018}\x{2019}\x{FF02}\x{FF07}]' pasted.sh
# 半角に置き換える(元のファイルを書き換える)
sed -i -e 's/[“”"]/"/g' -e "s/[‘’']/'/g" pasted.sh
1:curl -H “Content-Type: application/json” http://127.0.0.1/
2:print(‘ok’)
(置き換えたあと)
curl -H "Content-Type: application/json" http://127.0.0.1/
print('ok')
echo "fine"
置き換えたあとに同じ grep をかけると、件数は 0 でした。英文の中のアポストロフィ(don’t の ’)も置き換わるので、文章のファイルにはかけず、コードのファイルだけにします。 GNU grep の -P が使えない環境では、エディターの検索で “ と ” を探します。VS Code などのエディターは、紛らわしい Unicode 文字に枠を付けて表示する機能を持っています。
Python で Windows のパスを書いたときの \ のエラーは、関連記事「unicodeescapeエラーの直し方|Windowsのパス」で扱っています。
ダブルクォーテーションの入力方法(Windows・Mac・スマホ・Linux)
この節では、キーボードでダブルクォーテーションとシングルクォーテーションを打つ方法と、勝手に全角や“”になるときの設定が分かります。
日本語配列(JIS)
" は Shift+2、' は Shift+7。Windows も Mac の JIS キーボードも同じ位置。
キーの印字で確かめる
英語配列(US)
' は Enter の左のキー、" はそのキーを Shift と一緒に押す。
` は 1 の左
半角で入れる
日本語入力をオフ(半角英数)にしてから押す。オンのままだと全角の記号が候補に出る。
コードは必ず半角
スマホ
英語のキーボードの記号の画面(123)にある。押し続けると “ ” などの候補が出る機種もある。
スマート句読点に注意
勝手に“”になるときの設定(公式で確かめた範囲)
Mac:「スマート引用符とダッシュを使用する」を切る
アップルメニュー →「システム設定」→ サイドバーの「キーボード」→「テキスト入力」の「編集」を開き、「スマート引用符とダッシュを使用する」を切る。同じ画面の「二重引用符」「一重引用符」で、置き換える記号の形も選べる。アプリごとには「編集」→「自動置換」メニューで切り替えられる。
iPhone:「スマート句読点」を切る
「設定」→「一般」→「キーボード」→「スマート句読点」を切る。Apple サポートによると、この設定はほかのアプリにも効き、すでに入力した文字は変わらない。
Word・PowerPoint:オートフォーマットの引用符を切る
「ファイル」→「オプション」→「文章校正」→「オートコレクトのオプション」を開き、「入力オートフォーマット」タブで、引用符を左右の区別がある記号に変える項目のチェックを外す。手順書にコマンドを貼る文書では、ここを切っておくとコピーしても動く。
共有する側:コードはコードの枠に貼る
チャットや Wiki では、本文ではなくコードブロック(バッククォート3つで囲むなど)に貼ると、引用符が置き換わらない。受け取ったら、実行する前に前の節の grep で確かめる。
Linux のデスクトップは、配列の設定(日本語なら JIS)に合わせて Windows と同じ位置で入ります。ターミナルでは、文書ソフトのような自動の置き換えは起きません。Android は機種とキーボードのアプリで画面が違うため、記号の画面で半角の " を選びます。
Google 検索のダブルクォーテーション
Google 検索ヘルプ「Google 検索の結果を絞り込む」は、単語やフレーズの完全一致を検索するには引用符で囲んで入力する、と説明しています(例:"世界一高い建築物")。エラーの文言を調べるときは、文言をダブルで囲むと、その並びを含むページに絞れます。
どちらを使うか:場面別の判断表
この節では、迷ったときにダブルとシングルのどちらで囲むかを、場面ごとに決められます。
決まりがある場所(JSON・SQL・CSV・型のある言語)は決まりに従い、どちらでもよい場所(Python・JS・HTML)はチームの整形ツールに合わせます。
| やりたいこと | 使う記号 | 理由 |
|---|---|---|
| bash で変数を展開した文字列 | "$var" | 展開しつつ空白で分かれない |
| bash で正規表現・$ を含む文字 | '…' | 何も解釈させない |
| PHP・Ruby で変数を埋め込む | "…" | 展開はダブルだけ |
| Python・JS の文字列 | チームの規則(Black・Prettier の既定はダブル) | 意味は同じ。差分を出さない |
| JS で変数を埋め込む | `…${x}…` | 展開はテンプレートリテラルだけ |
| JSON のキーと文字列 | "…" | 規格でこれだけ |
| SQL の値 | '…'(中の ' は '') | どのデータベースでも値 |
| SQL の列名に予約語・大文字 | "…"(MySQL は `…`) | 名前として扱う |
| Java・C・Go・Rust の文字列 | "…" | シングルは1文字の型 |
| 中に " を含む文字列 | 外を '…' | エスケープが要らない |
- 1形式に決まりがあるかJSON・CSV は "、SQL の値は '。ここで決まる
- 21文字の型がある言語かJava・C・Go・Rust は、文字列なら "
- 3中で変数を展開したいかbash・PHP・Ruby・PowerShell は、展開するなら "、しないなら '
- 4中に引用符を含むか含むほうと逆の記号で囲み、エスケープを減らす
- 5残りはチームの規則に揃える整形ツールに任せ、手で混ぜない
- 1コードの引用符は半角かコピーしたものは grep で “ ” ‘ ’ を探す
- 2シェルの変数はダブルで囲んだかファイル名に空白があっても1つで渡る
- 3SQL の値はシングル、値はプレースホルダーかダブルは列名。値を文字列の連結で組み立てない
- 4JSON はダブルだけかprint した Python の辞書をそのまま使っていない
よくある質問
Q. ダブルクォーテーションとは何ですか? A. 「"」の記号で、日本語では二重引用符と呼びます。文章では引用や強調、プログラミングでは文字列を囲むのに使います。文書で使う向きのある「“ ”」は、キーボードの「"」とは別の文字です。
Q. シングルクォーテーションとダブルクォーテーションの違いは何ですか? A. 書く場所で違います。bash・PHP・Ruby・PowerShell ではダブルだけが中の変数を展開します。Java・C・Go・Rust ではシングルが1文字、ダブルが文字列です。SQL ではシングルが値、ダブルが列名です。Python と JavaScript では違いがありません。
Q. Python ではどちらを使うのが正しいですか? A. どちらも同じ文字列で、正しい・間違いはありません。PEP 8 もどちらかを勧めておらず、決めた規則を守るように書いています。整形ツールの Black を使うならダブルに揃います。中に ' を含む文字列はダブル、" を含む文字列はシングルで囲むとエスケープが要りません。
Q. JavaScript ではどちらを使いますか? A. 'abc' と "abc" は同じです。プロジェクトの ESLint・Prettier の設定に合わせます。Prettier の既定はダブルです。変数を埋め込みたいときは、どちらでもなくバッククォートのテンプレートリテラルを使います。
Q. JSON でシングルクォーテーションを使うとエラーになるのはなぜですか? A. JSON の規格(RFC 8259)で、文字列は " で囲むと決まっているからです。キーも文字列なので同じです。手元では Python が「Expecting property name enclosed in double quotes」、Node.js が「Expected property name or '}'」、jq が「Invalid numeric literal」を出しました。
Q. SQL で column "…" does not exist と出ます。 A. 値をダブルクォーテーションで囲んでいる可能性が高いです。PostgreSQL などではダブルは列名なので、その名前の列を探してエラーになります。値はシングルで囲みます。SQLite はエラーにならず値として読むことがあるので、別のデータベースに移したときに初めて出ることもあります。
Q. キーボードでダブルクォーテーションはどこですか? A. 日本語配列のキーボードは Shift+2 です(シングルは Shift+7)。英語配列は Enter の左のキーを Shift と一緒に押します。日本語入力をオフにしてから押すと半角の " が入ります。
Q. ダブルクォーテーションが全角や“”になってしまいます。 A. 日本語入力がオンのままか、スマート引用符の設定が有効です。Mac は「システム設定」→「キーボード」→「テキスト入力」の「編集」で「スマート引用符とダッシュを使用する」を、iPhone は「設定」→「一般」→「キーボード」→「スマート句読点」を切ります。Word はオートコレクトのオプションの「入力オートフォーマット」で切り替えます。
Q. 文字列の中に同じ引用符を入れるにはどうしますか? A. 外側を逆の記号にするのがいちばん簡単です。同じ記号を使うなら、多くの言語では \" や \' とエスケープします。SQL・CSV・PowerShell のシングル・YAML のシングルは、記号を2つ重ねます('' や "")。bash のシングルの中にはシングルを書けないので、'it'\''s' のように一度閉じます。
Q. PHP はシングルクォーテーションのほうが速いのですか? A. 手元の PHP 8.3 では、変数を含まない文字列は、シングルでもダブルでも同じ命令(ASSIGN string("hello"))になり、2,000万回の代入でも差はばらつきの範囲でした。速さではなく、変数を展開したいかで選びます。
Q. バッククォート(`)とはどう違いますか? A. 別の記号で、意味も違います。JavaScript ではテンプレートリテラル、bash では以前からあるコマンド置換の書き方(今は $(…) を使うのが一般的)、Go では raw 文字列、MySQL では列名・表名を囲む記号です。日本語配列では Shift+@ で入ります。
まとめ
- ダブルクォーテーションは「"」、シングルクォーテーションは「'」。文書の「“ ”」「‘ ’」はキーボードの記号とは別の文字。
- bash・PHP・Ruby・PowerShell では、ダブルだけが変数を展開する。シェルの変数は "$var" で囲む。
- Java・C・Go・Rust では、シングルは1文字の型。シングルで文字列を書くとコンパイルエラー(C は警告だけ)。
- JSON・CSV はダブルだけ。SQL は値がシングル、名前がダブル。SQLite はダブルの間違いがエラーにならないことがある。
- コピーで混ざった“”は、Python なら U+201C のエラーで分かる。grep で探して sed で半角に直し、元の文書のスマート引用符の設定を切る。
参考・出典
確認日はいずれも 2026年10月29日です。
- GNU「Bash Reference Manual」3.1.2 Quoting:https://www.gnu.org/software/bash/manual/bash.html#Quoting
- Python「字句解析」文字列およびバイト列リテラル:https://docs.python.org/ja/3/reference/lexical_analysis.html#string-and-bytes-literals
- Python「PEP 8 – Style Guide for Python Code」String Quotes:https://peps.python.org/pep-0008/#string-quotes
- Black「The Black Code Style」Strings:https://black.readthedocs.io/en/stable/the_black_code_style/current_style.html
- MDN「テンプレートリテラル」:https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals
- Prettier「Options」Quotes:https://prettier.io/docs/options
- PHP マニュアル「文字列」:https://www.php.net/manual/ja/language.types.string.php
- Microsoft Learn「about_Quoting_Rules」:https://learn.microsoft.com/ja-jp/powershell/module/microsoft.powershell.core/about/about_quoting_rules
- IETF「RFC 8259 The JavaScript Object Notation (JSON) Data Interchange Format」7. Strings:https://www.rfc-editor.org/rfc/rfc8259#section-7
- IETF「RFC 4180 Common Format and MIME Type for Comma-Separated Values (CSV) Files」:https://www.rfc-editor.org/rfc/rfc4180
- PostgreSQL「字句構造」:https://www.postgresql.jp/document/16/html/sql-syntax-lexical.html
- MySQL「MySQL 8.4 Reference Manual」11.1.1 String Literals:https://dev.mysql.com/doc/refman/8.4/en/string-literals.html
- SQLite「Quirks, Caveats, and Gotchas In SQLite」8. Double-quoted String Literals Are Accepted:https://www.sqlite.org/quirks.html
- Apple サポート「Macの『入力ソース』設定を変更する」:https://support.apple.com/ja-jp/guide/mac-help/mchl84525d76/mac
- Apple サポート「iPhoneのKeynoteでダッシュおよび引用符をフォーマットする」:https://support.apple.com/ja-jp/guide/keynote-iphone/tan30a88784c/ios
- Microsoft サポート「Word と PowerPoint のスマート引用」:https://support.microsoft.com/ja-jp/topic/702fc92e-b723-4e3d-b2cc-71dedaf2f343
- Google 検索ヘルプ「Google 検索の結果を絞り込む」:https://support.google.com/websearch/answer/2466433?hl=ja
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ダブルクォーテーションとシングルクォーテーションの違い|10言語で実行」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。