🍺

プログラムの文字列表現、あるいはクォーテーションの使い分けの話

10 min read

きっかけ

https://twitter.com/alfnet_info/status/1455403605494620172

をみて、今の世の中はどんなことになっているのかと思った次第。

本題

一応話のきっかけの人がJavaScriptとPythonが学校教育で多く使われているからという補足をしているので、
JavaScriptとPythonを先頭に、後はなるべく辞書順になるように記載したいと思います。

JavaScript

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String

バッククォートで囲うと(エスケープ文字ではない)改行も使えます。

別枠で扱うか迷いましたが、TypeScriptも同様だと思ってます。

Python

https://docs.python.org/ja/3/reference/lexical_analysis.html?highlight=文字列#string-and-bytes-literals
  • シングルクォート:shortstring
  • ダブルクォート:shortstring
  • その他

shortstringとlognstringの違いは

shortstring     ::=  "'" shortstringitem* "'" | '"' shortstringitem* '"'
longstring      ::=  "'''" longstringitem* "'''" | '"""' longstringitem* '"""'
shortstringitem ::=  shortstringchar | stringescapeseq
longstringitem  ::=  longstringchar | stringescapeseq
shortstringchar ::=  <any source character except "\" or newline or the quote> ここ と
longstringchar  ::=  <any source character except "\"> ここ

shortstringcharは\と改行とクォートは文字に含まれないのに対し、
longstringcharは\のみが文字に含まれないってことですね。
普段使っている人は体感で分かっていると思いますが、要は三重引用符だと改行が使えます。

C#

https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/char
https://docs.microsoft.com/ja-jp/dotnet/csharp/language-reference/builtin-types/reference-types#the-string-type
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル

C#の場合は文字列としてシングルクォーテーションで囲むのは間違いです。

C++

https://docs.microsoft.com/ja-jp/cpp/cpp/string-and-character-literals-cpp?view=msvc-160
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル
  • その他
    • お尻にs:std::stringリテラル

JSで言う文字列リテラルはstd::stringリテラルが近いと思います。(ごめんなさい、多分です。エアプです)

Cの場合は文字列としてシングルクォーテーションで囲むのは間違いです。

Clojure

https://www.clojure.org/guides/learn/syntax#_character_types
https://www.clojure.org/guides/learn/syntax#_delaying_evaluation_with_quoting
  • シングルクォート:評価遅延
  • ダブルクォート:文字列リテラル
  • その他
    • バックスラッシュ+文字:文字リテラル

COBOL

gnucobol

https://gnucobol.sourceforge.io/HTML/gnucobpg.html#Literals
  • シングルクォート:Alphanumeric Literals
  • ダブルクォート:Alphanumeric Literals

Crystal

https://ja.crystal-lang.org/reference/syntax_and_semantics/literals/index.html
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル(変数展開有)
  • その他
    • ダブルクォートの頭にコロン:シンボル(ダブルクォートが無くてもシンボル)
    • パーセント+特定の区切り文字:文字列リテラル(変数展開有)
    • パーセント+q+特定の区切り文字:文字列リテラル(エスケープ無し)
    • パーセント+Q+特定の区切り文字:文字列リテラル(変数展開有)

CSS

https://developer.mozilla.org/ja/docs/Web/CSS/string
  • シングルクォート:<string> データ型
  • ダブルクォート:<string> データ型

JSでは使えるけどバッククォートはNG

Dart

https://dart.dev/guides/language/language-tour#strings
  • シングルクォート:文字列リテラル(変数展開有り)
  • ダブルクォート:文字列リテラル(変数展開有り)
  • その他
    • クォートの頭にr:文字列リテラル(エスケープ無し)
    • クォート三つ:文字列リテラル(改行有り、変数展開有り)
    • クォート三つの頭にr:文字列リテラル(改行有り、エスケープ無し)

Delphi

https://docwiki.embarcadero.com/RADStudio/Sydney/ja/文字定数
https://docwiki.embarcadero.com/RADStudio/Sydney/ja/文字列定数
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル

Elixir

https://elixir-lang.org/getting-started/basic-types.html#strings
https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html
https://elixir-lang.org/getting-started/sigils.html#strings-char-lists-and-word-lists-sigils
  • シングルクォート:文字リスト
  • ダブルクォート:文字列リテラル(変数展開有、改行有)
  • その他
    • クエスチョン+文字:文字リテラル
    • チルダ+s+特定の区切り文字:ダブルクォート相当
    • チルダ+c+特定の区切り文字:シングルクォート相当
    • チルダ+S+特定の区切り文字:文字列リテラル

Erlang

https://www.erlang.org/doc/reference_manual/data_types.html
  • シングルクォート:アトム
  • ダブルクォート:文字列リテラル
  • その他
    • シングルクォートで囲まなくてもアトム

F#

https://docs.microsoft.com/ja-jp/dotnet/fsharp/language-reference/literals
http://dungpa.github.io/fsharp-cheatsheet/
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル
  • その他
    • ダブルクォート三つ:文字列リテラル(エスケープ無し)
    • ダブルクォートの頭に@:文字リテラル(エスケープ無しに近い)

Go

https://golang.org/ref/spec#Rune_literals
https://golang.org/ref/spec#String_literals
  • シングルクォート:rune_lit(文字リテラル)
  • ダブルクォート:interpreted_string_lit(文字列リテラルでエスケープ有)
  • その他
    • バッククォート:raw_string_lit(文字列リテラルでエスケープ無し改行有)

Groovy

https://groovy-lang.org/syntax.html#all-strings
  • シングルクォート:文字列リテラル
  • ダブルクォート:文字列リテラル(変数展開有)
  • その他
    • シングルクォート三つ:文字列リテラル(改行有)
    • ダブルクォート三つ:文字列リテラル(変数展開有、改行有)
    • スラッシュ:文字列リテラル(エスケープ無しに近い、0文字はコメントと被るのでNG)
    • ダラー+スラッシュ:文字列リテラル(スラッシュのみより更にエスケープ無しに近い)

Haskell

https://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-200002.6
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル

HSP

http://www.onionsoft.net/hsp/v33/doclib/hsp3str.htm
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル

Java

https://docs.oracle.com/javase/specs/jls/se12/html/jls-3.html#jls-3.10
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル

Javaの場合は文字列としてシングルクォーテーションで囲むのは間違いです。

Julia

https://docs.julialang.org/en/v1/manual/strings/
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル
  • その他
    • ダブルクォート三つ:文字列リテラル

kotlin

https://kotlinlang.org/docs/basic-types.html#characters
https://kotlinlang.org/docs/basic-types.html#strings
  • シングルクォート:文字リテラル
  • ダブルクォート:String templates
  • その他
    • ダブルクォート三つ:raw string (変数展開は有)

LISP

common-lisp

https://common-lisp.net/project/ecl/static/manual/Characters.html
http://www.lispworks.com/documentation/HyperSpec/Body/02_dc.htm
http://www.lispworks.com/documentation/HyperSpec/Body/02_de.htm
  • シングルクォート:expression
  • ダブルクォート:文字列リテラル
  • その他
    • シャープ+バックスラッシュ+文字:文字リテラル

Matlab

https://www.mathworks.com/help/matlab/characters-and-strings.html

https://memo-nikki.info/?p=666
  • シングルクォート:文字列リテラル?文字リテラルだけど連続して書けて配列化してくれる感じ?
  • ダブルクォート:文字列リテラル

Objective-C

???

何をObjective-Cの公式と呼べばいいか知識不足で判断つかず。

  • シングルクォート:おそらくC準拠で文字リテラル?
  • ダブルクォート:おそらくC準拠で文字列リテラル?

Perl

https://www.perltutorial.org/perl-string/
  • シングルクォート:文字列リテラル
  • ダブルクォート:文字列リテラル(変数展開有)
  • その他
    • q特定の記号で囲む:シングルクォート代替
    • qq特定の記号で囲む:ダブルクォート代替

PHP

https://www.php.net/manual/ja/language.types.string.php
  • シングルクォート:文字列リテラル(エスケープも最小限)
  • ダブルクォート:テンプレートリテラルに近い文字列リテラル(変数展開有)
  • その他
    • <<<string:ヒアドキュメント <<<の後ろに書いた文字列が出てくるまで全部。jsのテンプレートリテラルの使い勝手はこっち
    • <<<'string':Nowdoc <<<の後ろに書いた文字列が出てくるまで全部。シングルクォートとほぼ同じ性質

単に文字列の定義と言った場合は基本的にシングルクォーテーションで囲います。

R

???

PDFのどこかに記載あるんですかね? ちょっと無理でした

https://www.google.com/search?q=site%3Acran.r-project.org+string
  • シングルクォート:?(サンプル等から文字列リテラルであろうことはなんとなく分かる)
  • ダブルクォート:?(サンプル等から文字列リテラルであろうことはなんとなく分かる)

Ruby

https://docs.ruby-lang.org/ja/latest/doc/spec=2fliteral.html#string
  • シングルクォート:文字列リテラル(エスケープも最小限)
  • ダブルクォート:テンプレートリテラルに近い文字列リテラル(変数展開有)
  • その他
    • ?の後に文字を1字:文字リテラル
    • バッククォート:コマンド出力
    • <<string:ヒアドキュメント <<の後ろに書いた文字列が出てくるまで全部。
      • シングルクォート,ダブルクォート,バッククォートでstringを囲むことでそれぞれの性質を付与

Rust

https://doc.rust-lang.org/reference/tokens.html#literals
  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル
  • その他
    • ダブルクォートの頭にr:文字列リテラル(エスケープ無し)

Scala

https://www.scala-lang.org/files/archive/spec/2.11/01-lexical-syntax.html#character-literals
https://docs.scala-lang.org/ja/overviews/core/string-interpolation.html
https://www.ne.jp/asahi/hishidama/home/tech/scala/literal.html#h_String)

※docsにろくな情報が無いのはどういうことなんですかね?

  • シングルクォート:文字リテラル
  • ダブルクォート:文字列リテラル
  • その他
    • ダブルクォート三つ:文字列リテラル(改行有、エスケープ無しに近い)
    • ダブルクォートの頭にs:文字リテラル(変数展開有)
    • ダブルクォートの頭にf:文字リテラル(書式付き変数展開有)
    • ダブルクォートの頭にraw:文字リテラル(変数展開有、エスケープ無し)
    • ダブルクォートの頭にメソッド名:カスタム補間子(StringContextもしくはStringContext に新しいメソッドを追加した際のメソッド名、上記三つも実際はコレ)
    • シングルクォート(囲まない):シンボル(より厳密な定数みたいな感じの印象)
    • XML:XML

shell

bash

https://www.gnu.org/software/bash/manual/html_node/Quoting.html#Quoting
  • シングルクォート:inhibit all interpretation
  • ダブルクォート:suppress most of the interpretation
    • 頭にダラー:ANSI-C Quoting

SQL

postgresql

https://www.postgresql.jp/document/9.6/html/sql-syntax-lexical.html#sql-syntax-strings
  • シングルクォート:文字列リテラル
  • ダブルクォート:引用符付き識別子

Swift

https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html
  • シングルクォート:?(文字リテラル?)
  • ダブルクォート:文字列リテラル(変数展開有)
  • その他
    • ダブルクォート三つ:文字列リテラル(改行有)
    • ダブルクォートの頭に#:文字列リテラル(エスケープ無しに近い、変数展開有だが記法が#無しと異なる)

VBA

https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/language-features/strings/string-basics
https://docs.microsoft.com/ja-jp/dotnet/visual-basic/programming-guide/program-structure/comments-in-code
  • シングルクォート:コメント
  • ダブルクォート:文字列リテラル(改行有)
  • その他
    • ダブルクォートのお尻にc:文字リテラル

なでしこ

https://nadesi.com/v3/doc/index.php?文法&show
  • シングルクォート:?
  • ダブルクォート:文字列リテラル(改行有)(ドキュメントを眺めるとたまに「」の代わりに出てくる)
  • その他
    -「」:文字列リテラル(変数展開有)

調査するプログラム言語を何にするかの参考にした情報

https://octoverse.github.com/

https://insights.stackoverflow.com/survey/2021

調査中に見つけたサイト

https://www.programming-idioms.org/idiom/48/multi-line-string-literal

まとめ

文字列ではないものは×
変数展開が伴うなど定数定義には向かなそうなものは※
上記以外は〇
にしたつもりです

言語 シングル ダブル 備考
JavaScript
Python
C# ×
C++ ×
Clojure ×
COBOL 自信ありません!
Crystal ×
CSS
Dart 区別は無さそうだけどどちらも変数展開有
Delphi ×
Elixir ×
Erlang ×
F# ×
Go ×
Groovy 使い分けるのがおススメ
Haskell ×
HSP ×
Java ×
Julia ×
kotlin × 変数展開がされないパターンが無い?
LISP ×
Matlab シングルは判断つかず
Objective-C × たぶん
Perl 使い分けるのがおススメ
PHP 使い分けるのがおススメ
R 力不足の為、公式から拾えませんでした
Ruby 使い分けるのがおススメ
Rust ×
Scala ×
shell
SQL(postgresql) ×
Swift × 変数展開有
VBA ×
なでしこ ×

どちらも〇の場合は文字列内に引用符を使う機会が少ない方を選択するのがおススメです。
例えばSQLをORM使わずに書く機会が多い場合は二重引用符を使うのが楽ですね。

ドキュメントを読んでから作業をするクセを付けたいですね!

お疲れさまでした。

Discussion

ログインするとコメントできます