結論

ダブルクォーテーション(")とシングルクォーテーション(')は、どちらも文字列を囲む記号ですが、bash・PHP・Ruby では「中の変数を展開するか」、JSON・SQL・Java・C では「使える場所そのもの」が違います。Python と JavaScript では、どちらで囲んでも同じ文字列です。

この記事でわかること

  • bash・Python・PHP・SQL など10言語で動かした出力の違い
  • 全角の“”を貼ったときのエラー原文と、見つけて直す方法
  • Windows・Mac・スマホでの入力方法と、場面別の判断表

2026年10月29日更新|bash 5.2・Python 3.13・PHP 8.3・PostgreSQL 16・Chromium 153で実行確認

同じ「引用符」でも、書く場所によって意味が変わります。まず、記号で意味が変わるかどうかで大きく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
117msシングル(3回の平均)変数なし・2,000万回
104msダブル(3回の平均)変数なし・2,000万回
同じ命令(opcode)どちらも ASSIGN string("hello")

変数の無い文字列では、回ごとのばらつきのほうが大きく、どちらが速いとは言えませんでした。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 &quot;hi&quot; 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

属性の中に同じ記号を入れると、そこで値が終わります。&quot; と書くか、外側を逆の記号にします。全角の“”で囲んだ href は、エラーは出ずに、壊れたリンクになりました。 Python の html.escape() は、既定で " を &quot;、' を &#x27; に変えました。

全角・スマート引用符(“”)を貼ったときのエラー原文と直し方

この節では、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)

この節では、キーボードでダブルクォーテーションとシングルクォーテーションを打つ方法と、勝手に全角や“”になるときの設定が分かります。

1

日本語配列(JIS)

" は Shift+2、' は Shift+7。Windows も Mac の JIS キーボードも同じ位置。

キーの印字で確かめる

2

英語配列(US)

' は Enter の左のキー、" はそのキーを Shift と一緒に押す。

` は 1 の左

3

半角で入れる

日本語入力をオフ(半角英数)にしてから押す。オンのままだと全角の記号が候補に出る。

コードは必ず半角

4

スマホ

英語のキーボードの記号の画面(123)にある。押し続けると “ ” などの候補が出る機種もある。

スマート句読点に注意

勝手に“”になるときの設定(公式で確かめた範囲)

1

Mac:「スマート引用符とダッシュを使用する」を切る

アップルメニュー →「システム設定」→ サイドバーの「キーボード」→「テキスト入力」の「編集」を開き、「スマート引用符とダッシュを使用する」を切る。同じ画面の「二重引用符」「一重引用符」で、置き換える記号の形も選べる。アプリごとには「編集」→「自動置換」メニューで切り替えられる。

Apple サポート「Macの『入力ソース』設定を変更する」

2

iPhone:「スマート句読点」を切る

「設定」→「一般」→「キーボード」→「スマート句読点」を切る。Apple サポートによると、この設定はほかのアプリにも効き、すでに入力した文字は変わらない。

Apple サポート(Keynote の iPhone 版ユーザガイド)

3

Word・PowerPoint:オートフォーマットの引用符を切る

「ファイル」→「オプション」→「文章校正」→「オートコレクトのオプション」を開き、「入力オートフォーマット」タブで、引用符を左右の区別がある記号に変える項目のチェックを外す。手順書にコマンドを貼る文書では、ここを切っておくとコピーしても動く。

Microsoft サポート「Word と PowerPoint のスマート引用」

4

共有する側:コードはコードの枠に貼る

チャットや Wiki では、本文ではなくコードブロック(バッククォート3つで囲むなど)に貼ると、引用符が置き換わらない。受け取ったら、実行する前に前の節の grep で確かめる。

チャット・Wiki・メール

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. 1形式に決まりがあるかJSON・CSV は "、SQL の値は '。ここで決まる
  2. 21文字の型がある言語かJava・C・Go・Rust は、文字列なら "
  3. 3中で変数を展開したいかbash・PHP・Ruby・PowerShell は、展開するなら "、しないなら '
  4. 4中に引用符を含むか含むほうと逆の記号で囲み、エスケープを減らす
  5. 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期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ
参加受付中

AI駆動開発、 無料セミナー