文字列リテラル、または匿名文字列とは、ソースコード内の文字列値を表すリテラルです。一般的に、プログラミング言語には、括弧(通常は引用符)で囲まれた一連の文字である文字列リテラルというコード構造が含まれています。多くの言語では、テキストは文字列リテラルとしてエンコードされますが、他にも多くのバリエーションがあります。"foo"foo
括弧で囲まれた文字列リテラルは、開始文字と終了文字によって区切られます。言語によっては、任意の文字を区切り文字として指定できます。
引用符は、文字列リテラルを区切る最も一般的な方法です。多くの言語は、二重引用符(例:`"` "Hello")と単一引用符(例:`"` 'there')の両方をサポートしています。両方がサポートされている場合、一方のスタイルの引用符で囲まれた文字列を通常のテキストとして扱うことで、区切り文字の衝突を最小限に抑えることができます。Python では、外側の引用符が二重引用符であるため、内側の単一引用符が通常のテキストとなり、このリテラルは"Dwayne 'the rock' Johnson"有効です。
空の文字列は""またはと表記されます''。
ペア区切り文字は、リテラルの先頭で使用され、末尾で使用される2種類の異なる文字です。ペア区切り文字を使用すると、言語はリテラル テキストに引用符を埋め込むことができます。ただし、引用符はすべてペアになっており、スコープから部分的に飛び出さないことが条件です。たとえば、PostScript では、括弧を使用します (例: および(The quick (brown fox))m4 ) 。バッククォートを`先頭に、アポストロフィを'末尾に使用します。Tclでは、引用符と中括弧の両方を使用できます (例: または"The quick brown fox") 。これは、Unix シェルのシングル クォーテーションと、 C{The quick {brown fox}}言語の複合ステートメントでの中括弧の使用に由来します。Tcl では、コード ブロックは構文上、文字列リテラルと同じであるため、区切り文字がペアになっていることが、これを可能にするために不可欠です。
引用符は通常、ペアのない引用符で表されますが、一部のツールや文字セットはペアのある引用符をサポートしています。ペアのない引用符とは、左側の引用符と右側の引用符の固有のバリエーションを持たない引用符のことで、""や などが含まれます''。Unicode文字セットには、ペアのあるバージョンが含まれています。
"やあ!" 'やあ!' "やあ!" "やあ!"
スコープミキシングとは、スコープが純粋な階層構造ではなく、混在している状態を指します。 [ a ]
言い換えれば、「スコープの混在」とは、明確な開始区切り文字(または明確な終了区切り文字)が存在しない状態を指します。
引用符が自身のスコープから外れてしまう例(不正な文字列)としては、以下のようなものがあります。
"InsideTheOuterString 'InnerString_ButWithUnmatchedEndingSingleQuoteThatRendersThisStringInvalid" ErroneousStringThatIsSomehowInsideTheInnerStringYetNotInsideTheOuterString'"1 '2" 3'"Inside1 'InsideBoth1and2" Inside2'文字列リテラルはスコープの混在を許可しません。混在するとプログラムが曖昧になるからです。文字列リテラルはスコープが混在しているように見えることがありますが、曖昧さを防ぐために、各プログラミング言語ごとに演算子の優先順位ルール[ b ] が定められています。例えば、式を左端の文字から右端の文字まで読み取ることで、左端の"記号に、その後に続く(同じ行にある)他の引用符よりも高い優先順位(つまり、優先権)を与えるといったルールです。
前述のように、ネストされた引用符は、 のように有効です"Dwayne 'the rock' Johnson"が、階層構造(通常はスタックデータ構造)を使用する何らかの方法が必要です。その階層構造が、一意の区切り文字、エスケープ文字、または繰り返し文字の区切り文字を使用するかどうかは関係ありません。
「スコープ混合」は、区切り文字の衝突の特殊なケースであり、このページの後半で説明します。
言語によっては、複数行の文字列をサポートしている場合があります。YAMLでは、文字列リテラルは、空白文字とインデントの相対的な位置によって指定できます。
- title : YAML の複数行文字列の例body : |これは複数行の文字列です。「特殊」メタ文字がここに現れることがあります。この文字列の範囲はインデントで表されます。PerlやPHPなどの一部の言語では、自然言語の単語と同じように区切られた文字列リテラルを使用できます。たとえば、次のPerlコードでは、引用符で囲まれていませんがred、、、、greenはblue文字列リテラルです。
%map = ( red => 0x00f , blue => 0x0f0 , green => 0xf00 );Perlでは、予約語ではない英数字のシーケンスは、ほとんどの場合、文字列リテラルとして扱われます。例えば、次の2行のPerlコードは同等です。
$y = "x" ; $y = x ;リテラルの長さはテキストの先頭にエンコードできるため、文字列の開始と終了をマークする必要がなくなります。たとえば、FORTRANでは、文字列リテラルはホレリス記法で記述されていました。これは、文字数を10進数で表した後に文字「H」が続き、その後に文字列の文字が続くというものです。
35ハンの例ホレリス文字列リテラルこの手法の欠点は、長さ挿入が自動化されていない限り、特にマルチバイトエンコーディングの場合、比較的エラーが発生しやすいことです。利点としては、終了区切り文字の検索が不要になるため計算オーバーヘッドが少なくなり、区切り文字の衝突問題を防止し、そうでなければコマンドと誤認される可能性のあるメタ文字を含めることができる点が挙げられます。
引用符を使用する場合、文字列リテラルで区切り文字自体を表現しようとすると、区切り文字の衝突という問題に遭遇します。たとえば、区切り文字が二重引用符の場合、2 番目の引用符が"""文字列の値ではなく文字列リテラルの終わりとして解釈されるため、リテラルで二重引用符自体を単純に表現することはできません。同様に、"This is "in quotes", but invalid."中央の引用符で囲まれた部分が引用符の外側として解釈されるため、と記述することもできません。さまざまな解決策がありますが、最も一般的なのは、やなどのエスケープシーケンスを使用することです"\""。"This is \"in quotes\" and properly escaped."しかし、他にも多くの解決策があります。
Tcl の波括弧のようなペアの引用符は、ネストされた文字列を許可しますが、{foo {bar} zork}それ以外の方法では区切り文字の衝突の問題を解決しません。なぜなら、不均衡な閉じ区切り文字は、のように単純に含めることができないからです{}}。
Pascal、BASIC、DCL、Smalltalk、SQL、J、Fortranなど、多くの言語では、文字列リテラルの一部となることを意図した引用符を二重にすることで、区切り文字の衝突を回避しています。
「このパスカル文字列にはアポストロフィが2つ含まれています」「聞こえますか?」と私は言った。Fortran、Modula-2、JavaScript、Python、PHPなどの一部の言語では、複数の引用符区切り文字を使用できます。2つの区切り文字が使用可能な場合、これは二重引用符と呼ばれます。通常、これはプログラマが単一引用符と二重引用符を交互に使用できることを意味します。各リテラルは、どちらか一方を使用する必要があります。
「これはジョンのリンゴだよ。」「聞こえますか?」と私は言った。ただし、この方法では、区切り文字を両方含む単一のリテラルを持つことはできません。この問題は、複数のリテラルを使用し、文字列連結を行うことで回避できます。
「私は『これはジョンのリンゴです』と言いました。」Pythonには文字列リテラルの連結機能があるので、連続する文字列リテラルは演算子なしでも連結されます。したがって、これは次のように簡略化できます。
「これはジョンのリンゴだよ」と私は言った。C++11では、いわゆる生文字列リテラルが導入されました。これらは基本的に、
R" end-of-string-id ( content ) end-of-string-id "、つまり、R"プログラマーは、文字列の末尾 ID (文字列の末尾を示すために繰り返される目的、略してeos id ) を形成する空白文字、括弧、バックスラッシュを除く最大 16 文字を入力できます。次に、開始括弧 (eos id の末尾を示すため) が必要です。次に、リテラルの実際の内容が続きます。任意のシーケンス文字を使用できます (ただし、閉じ括弧の後に eos id と引用符が続くことはできません)。最後に、文字列を終了するために、閉じ括弧、eos id、引用符が必要です。 このようなリテラルの最も単純なケースは、内容と eos id が空のものです。eos id 自体に引用符を含めることができますR"()"。は有効なリテラルです (eos id はここにあります)。 エスケープ シーケンスは、生の文字列リテラルでは機能しません。R""(I asked, "Can you hear me?")"""
D はいくつかの引用符区切り文字をサポートしており、そのような文字列は と開始q"区切り文字で始まり、それぞれの終了区切り文字 と で終わります"。使用可能な区切り文字のペアは()、<>、{}、 です[]。ペアになっていない非識別子区切り文字は、それ自体が終了区切り文字になります。ペアになった区切り文字はネストされるため、 はq"(A pair "()" of parens in quotes)"有効なリテラルです。ネストしない/文字を使用した例は ですq"/I asked, "Can you hear me?"/"。C ++11 と同様に、D では文字列の末尾 ID を持つヒアドキュメント形式のリテラルが使用できます。
q" end-of-string-id newline content newline end-of-string-id "Dでは、文字列の末尾のIDは識別子(英数字)でなければなりません。
shやPerlなどの一部のプログラミング言語では、区切り文字によって文字列補間を行うかどうかなど、扱いが異なるため、どの区切り文字を使用するかを選択する際には注意が必要です。詳しくは、下記の「さまざまな種類の文字列」のセクションを参照してください。
さらに、多重引用符を使用することで、文字列リテラルの境界を指定する文字を選択できるようになります。
例えば、Perlでは:
qq^私は「聞こえますか?」と言いました。^ qq@私は「聞こえますか?」と言いました。@ qq§私は「聞こえますか?」と言いました。§いずれも望ましい結果を生み出します。この表記法はより柔軟ですが、サポートしている言語は少なく、Perl 以外ではRuby (Perl の影響を受けている) とC++11もサポートしています。多重引用符のバリエーションとして、ヒアドキュメント形式の文字列の使用があります。
Lua(バージョン5.1以降)は、特に長いコメントや埋め込み文字列のネストを可能にするために、限定的な形式の多重引用符を提供します。通常、リテラル文字列(先頭の改行は削除され、それ以外はそのまま)を区切るには、`&` と `&`[[を使用します]]が、開き括弧には任意の数の等号を含めることができ、閉じ括弧に同じ数の等号が含まれている場合にのみ文字列が閉じられます。例:
local ls = [=[この表記は Windows パスにも使用できます: local path = [[C:\Windows\Fonts]] ]=]多重引用符は、引用符などの通常の区切り文字を含む正規表現で特に便利です。これにより、エスケープする必要がなくなります。初期の例としてはsedがあり、置換コマンドでは、デフォルトのスラッシュ区切り文字を別の文字に置き換えることができます。s/regex/replacement//s,regex,replacement,
現代のプログラミング言語ではあまり使われない別の方法として、文字列をリテラルで表現するのではなく、関数を使って文字列を構築する方法があります。これは、計算が構文解析時ではなく実行時に行われるため、現代のプログラミング言語では一般的に使用されません。
例えば、初期のBASICにはエスケープシーケンスやここに挙げたような回避策は含まれていなかったため、代わりにCHR$引数に対応する文字を含む文字列を返す関数を使用する必要がありました。ASCIIでは引用符の値は34なので、ASCIIシステムで引用符付きの文字列を表すには次のように記述します。
「私は言った、「」+ CHR$ ( 34 ) + 「聞こえますか?」+ CHR$ ( 34 )C言語では、同様の機能は「文字」書式指定子によって利用できますsprintfが%c、他の回避策が存在する場合は、一般的には使用されません。
char buffer [ 32 ]; snprintf ( buffer , sizeof buffer , "これは %cin の引用符です。%c" , 34 , 34 );これらのコンストラクタ関数は、非表示文字を表すためにも使用できますが、一般的にはエスケープシーケンスが使用されます。同様の手法は、C++ のstd::string文字列化演算子でも使用できます。
エスケープシーケンスは、区切り文字、非印刷文字(バックスペースなど)、改行、空白文字(視覚的に区別することが不可能な文字)など、直接表現するのが難しい文字を表現するための一般的な手法であり、長い歴史があります。そのため、文字列リテラルで広く使用されており、エスケープシーケンスを(単一の文字または文字列全体に追加する)ことはエスケープと呼ばれます。
直接含めるのが難しい、または不可能な文字のエンコーディングを与えるために、1 つの文字がプレフィックスとして選択されます。最も一般的なのはバックスラッシュです。他の文字に加えて、重要な点は、バックスラッシュ自体をダブルバックスラッシュとしてエンコードできること\\、および区切り文字付き文字列の場合、区切り文字自体をエスケープすることによってエンコードできることです。たとえば、\"" をエスケープします。このようなエスケープされた文字列の正規表現は、ANSI C仕様にあるように、次のように指定できます。[ 1 ] [ c ]
「」(\\.|[^\\"])*つまり、「引用符。その後にエスケープ文字(バックスラッシュの後に何か、おそらくバックスラッシュまたは引用符)が0個以上続くか、エスケープ文字でも引用符でもない文字が続き、最後に引用符で終わる」という意味です。唯一の問題は、終了引用符と、バックスラッシュの後に続く引用符を区別することです。バックスラッシュ自体もエスケープされている可能性があります。\uFFFFエスケープ方式によっては、バックスラッシュの後に複数の文字が続くことがあります。
エスケープされた文字列は、それ自体が字句解析され、エスケープされた文字列が表すエスケープされていない文字列に変換される必要があります。これは、コンピュータ言語全体の字句解析の評価フェーズで行われます。つまり、言語全体の字句解析器の評価器が、エスケープされた文字列リテラルに対して独自の字句解析器を実行します。
とりわけ、通常文字列定数を終了させる文字をエンコードできる必要があり、さらにエスケープ文字自体を指定する方法も必要です。エスケープシーケンスは必ずしも見栄えが良く使いやすいとは限らないため、多くのコンパイラは一般的な問題を解決するための他の手段も提供しています。しかし、エスケープシーケンスはすべての区切り文字の問題を解決し、ほとんどのコンパイラはエスケープシーケンスを解釈します。エスケープ文字が文字列リテラル内にある場合、それは「これがエスケープシーケンスの開始です」という意味です。すべてのエスケープシーケンスは、文字列に直接挿入される1文字を指定します。エスケープシーケンスで実際に必要な文字数は異なります。エスケープ文字はキーボードの左上にありますが、エディタが変換するため、文字列に直接貼り付けることはできません。バックスラッシュは、文字列リテラルでエスケープ文字を表すために使用されます。
多くのプログラミング言語は、文字列リテラル内でメタ文字を使用することをサポートしています。メタ文字の解釈は文脈や言語によって異なりますが、一般的には印刷文字または非印刷文字を表すための「処理コマンド」の一種です。
例えば、C言語の文字列リテラルにおいて、バックスラッシュの後に「b」、「n」、「t」などの文字が続く場合、それぞれ非印刷バックスペース、改行、タブ文字を表します。また、バックスラッシュの後に1~3桁の8進数が続く場合、このシーケンスは、リテラルのエンコーディングで指定された値を持つ任意のコード単位(例えば、ASCIIリテラルの対応するASCIIコード)を表すものとして解釈されます。これは後に、より現代的な16進数文字コード表記を可能にするために拡張されました。
「私は言った、聞こえますか?注:リストにあるすべてのシーケンスがすべてのパーサーでサポートされているわけではなく、リストに含まれていないエスケープシーケンスが存在する可能性があります。
あるプログラミング言語のコードを別の言語の中に埋め込む場合、埋め込まれた文字列には複数のエスケープ処理が必要になることがあります。これは、正規表現やSQLクエリを他の言語内で使用する場合、あるいはシェルスクリプト内で他の言語を使用する場合に特によく見られます。このような二重エスケープ処理は、読みにくく、作成も困難になることがよくあります。
ネストされた文字列の引用符が正しくないと、セキュリティ上の脆弱性が生じる可能性があります。SQLクエリのデータフィールドなど、信頼できないデータを使用する場合は、コードインジェクション攻撃を防ぐためにプリペアドステートメントを使用する必要があります。PHP 2から5.3までは、マジッククォートと呼ばれる機能があり、文字列を自動的にエスケープしていました(利便性とセキュリティのため)。しかし、問題が発生したため、バージョン5.4以降では削除されました。
一部のプログラミング言語では、リテラルを言語固有の解釈なしに処理するように指定する方法が提供されています。これにより、エスケープ処理が不要になり、より読みやすい文字列が得られます。
生文字列は、一般的な文字をエスケープする必要がある場合に特に便利です。特に、バックスラッシュが\広く使用される正規表現(文字列リテラルとしてネストされる)や、バックスラッシュがパス区切り文字として使用される DOS/Windowsパスなどで有効です。バックスラッシュが多用される状態は「傾いたつまようじ症候群」として知られており、生文字列を使用することでこれを軽減できます。C# でのエスケープされたパス名と生のパス名を比較してください。
「Windows のパスは C:\\Foo\\Bar\\Baz\\ です」@「Windows のパスは C:\Foo\Bar\Baz\ です」これらが組み合わさると極端な例が生じます。統一命名規則のパスは\\で始まるため、UNC 名に一致するエスケープされた正規表現は、"\\\\\\\\"文字列と正規表現の両方をエスケープする必要があるため、8 つのバックスラッシュ で始まります。生の文字列を使用すると、C# のように、これを 4 つ (正規表現でエスケープ) に減らすことができます@"\\\\"。
XML文書では、CDATAセクションを使用することで、&や<などの文字をXMLパーサーが文書の構造の一部として解釈しようとすることなく使用できます。これは、リテラルテキストやスクリプトコードを含める場合に、文書の形式を整然と保つために役立ちます。
<![CDATA[ if (path!=null && depth<2) { add(path); } ]]>多くの言語では、文字列リテラルに複数行にわたるリテラル改行を含めることができます。あるいは、改行はエスケープすることもできます。最も一般的な方法は です\n。例:
echo 'foo bar'そして
echo -e "foo\nbar"どちらも有効なBASHステートメントであり、どちらも同じ出力を生成します。
フー バー
リテラル改行を許可する言語には、BASH、Lua、Perl、PHP、R、Tclなどがあります。その他の言語では、文字列リテラルに改行を含めることはできません。
複数行の文字列リテラルには、先頭と末尾の改行とインデントという2つの問題があります。先頭または末尾の区切り文字が別々の行にある場合、余分な改行が発生します。一方、区切り文字が別々の行にない場合、特に最初の行はインデントが他の行と異なるため、区切り文字によって文字列が読みにくくなります。さらに、先頭の空白文字が保持されるため、リテラルはインデントされていない必要があります。リテラルがインデントされたコード内に存在する場合、コードの流れが途切れてしまいます。
これらの問題に対する最も一般的な解決策は、ヒア ドキュメントスタイルの文字列リテラルです。厳密に言えば、ヒア ドキュメントは文字列リテラルではなく、ストリーム リテラルまたはファイル リテラルです。これらはシェル スクリプトに由来し、リテラルを外部コマンドへの入力として渡すことができます。開始区切り文字は で、は任意の単語です。終了区切り文字は、コンテンツの境界として機能する単独の行にあります。 は、標準入力をリテラルからリダイレクトするためです。区切り文字は任意であるため、区切り文字の衝突の問題も回避されます。また、バリアント構文を使用して先頭のタブを削除できますが、先頭のスペースは削除されません。同じ構文は、その後、多くの言語、特に Perl で複数行の文字列リテラルに採用され、ヒア ドキュメントとも呼ばれ、文字列でありリダイレクトを伴わないにもかかわらず、構文を保持しています。他の文字列リテラルと同様に、変数補間などの異なる動作を指定できる場合があります。<<ENDENDEND<<<<-END
Pythonでは、通常の文字列リテラルではリテラル改行が使用できませんが、代わりに複数行リテラル用に設計されたトリプルクォーティング'''と呼ばれる特殊な文字列形式があります。これらは、またはのいずれかの3重の区切り文字を使用します。これらのリテラルは、特にドキュメント文字列"""として知られるインラインドキュメントに使用されます。
Tcl では文字列内にリテラル改行文字を使用できますが、複数行文字列を扱うための特別な構文はありません。ただし、区切り文字は行に単独で配置でき、先頭と末尾の改行文字は で削除できますstring trim。また、string mapを使用するとインデントを削除できます。
いくつかの言語では文字列リテラルの連結が提供されており、隣接する文字列リテラルがコンパイル時に暗黙的に単一のリテラルに結合されます。これは、C [ 7 ] [ 8 ]、C++ [ 9 ]、D [ 10 ]、Ruby [ 11 ] 、およびC からコピーしたPython [ 12 ]の機能です。 [ 13 ]注目すべきは、この連結はコンパイル時に字句解析中に発生し(最初のトークン化に続くフェーズとして)、実行時の文字列連結(一般的に+演算子を使用) [ 14 ]および定数畳み込み中の連結(コンパイル時に発生するが、後のフェーズ (句解析または「構文解析」の後) で発生する) とは対照的であることです。 C#、Java [ 15 ]、Perl などのほとんどの言語は、暗黙的な文字列リテラル連結をサポートしておらず、代わりに+演算子を使用した明示的な連結を必要とします (これは D と Python でも可能ですが、C/C++ では不正です - 下記を参照)。この場合、連結は定数畳み込みを介してコンパイル時に行われるか、実行時に延期される可能性があります。
この概念と用語の起源であるC言語では、文字列リテラル連結は2つの理由で導入されました。[ 16 ]
実際には、これにより、句解析や定数畳み込みを必要とせずに、コンパイルの初期段階(「翻訳」、具体的には字句解析の一部として)で文字列連結が可能になります。例えば、次のコードは有効なC言語です。
char s [] = "hello, " "world" ; printf ( "hello, " "world" );しかし、以下の記述は無効です。
char s [] = "hello, " + "world" ; printf ( "hello, " + "world" );これは、文字列リテラルが配列型(char[]C またはC++)を持ち、加算できないためです。これは他のほとんどの言語では制限ではありません。なお、C++ では文字列リテラルに対してオーバーロードされているconst char[]ことに注意してください。operator+
これは、特にマクロにおいて、前処理後に文字列を計算できるようにするために、Cプリプロセッサと組み合わせて使用する場合に特に重要です。 [ 13 ]簡単な例として、次のようになります。
char file_and_message [] = __FILE__ ": message" ;(ファイル名がacの場合)展開すると次のようになります。
char file_and_message [] = "ac" ": message" ;そして、それが連結され、以下と同等になります。
char file_and_message [] = "ac: メッセージ" ;一般的な使用例としては、フォーマット指定子がマクロによって与えられるフォーマット文字列の構築printf()やscanf()フォーマット文字列の作成があります。 [ 18 ] [ 19 ]
より複雑な例では、整数の文字列化(プリプロセッサによる)を使用して、文字列リテラルのシーケンスに展開されるマクロを定義し、それらをファイル名と行番号を含む単一の文字列リテラルに連結します。[ 20 ]
#define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) #define AT __FILE__ ":" TOSTRING(__LINE__)C/C++ の構文要件を超えて、暗黙的な連結は構文糖衣の一種であり、文字列リテラルを複数行に分割しやすくし、行継続 (バックスラッシュ経由) の必要性を回避し、文字列の一部にコメントを追加できるようにします。たとえば、Python では、次のように正規表現にコメントを付けることができます。 [ 21 ]
import re from re import Patternパターン: Pattern = re.compile ( " [A-Za-z_]" # 文字またはアンダースコア" [A-Za-z0-9_]*" # 文字、数字またはアンダースコア)現代のコンパイラは定数畳み込みを実装しているため、暗黙的な文字列連結は不要であり、特に文字列の水平リストにおいて、カンマの省略による意図しない連結が原因で、見つけにくいエラーが発生する。例:
l :リスト[ str ] = [ "foo" , "bar" "zork" ]そのため、ほとんどの言語では使用されておらず、D [ 22 ]および Python [ 13 ]では非推奨とされています。しかし、この機能を削除すると後方互換性が損なわれ、連結演算子に置き換えると優先順位の問題が発生します。文字列リテラルの連結は、演算子の評価の前に字句解析中に発生しますが、明示的な演算子による連結は他の演算子と同時に発生するため、優先順位が問題となり、目的の評価順序を保証するために括弧が必要になる可能性があります。
より微妙な問題は、C と C++ では[ 23 ]異なるタイプの文字列リテラルがあり、これらの連結の動作は実装依存であるため、潜在的なセキュリティリスクが生じることです。[ 24 ]
言語によっては、動作が異なる複数の種類の文字列リテラルが用意されています。これは主に、エスケープ処理のない文字列(生文字列)を示す場合や、変数補間を有効または無効にする場合に使用されますが、文字セットを区別するなど、他の用途にも使用されます。多くの場合、これは引用符を変更したり、接頭辞や接尾辞を追加したりすることで行われます。これは、 16進数や長整数を示す場合など、整数リテラルの接頭辞や接尾辞に相当します。
最も古い例の一つはシェルスクリプトにあり、そこではシングルクォートは生の文字列または「リテラル文字列」を示し、ダブルクォートはエスケープシーケンスと変数補間を表します。
例えば、Pythonでは、生の文字列の前にはrまたはが付きます。とR比較してください(ただし、Python の生の文字列は奇数個のバックスラッシュで終わることはできません)。Python 2 では、2 種類の文字列が区別されます。8 ビット ASCII ("バイト") 文字列 (デフォルト) は、または のプレフィックスで明示的に示され、Unicode 文字列は、または のプレフィックスで示されます。[ 25 ]一方、Python 3 では、文字列はデフォルトで Unicode であり、バイトは別の型で、引用符で初期化する場合は をプレフィックスとして付ける必要があります。'C:\\Windows'r'C:\Windows'bBuUbytesb
C#における生文字列の表記法は、@ クォーティングと呼ばれます。
@"C:\Foo\Bar\Baz\"これによりエスケープ処理は無効になりますが、二重引用符の使用は可能になり、文字列内で引用符を表現できるようになります。
「こんにちは」と私は言いました。C++11では、接頭辞によって定義される生文字列、Unicode文字列(UTF-8、UTF-16、UTF-32)、およびワイド文字文字列が使用できます。また、既存のC++文字列にリテラルが追加されstring、これは一般的に既存のCスタイルの文字列よりも推奨されます。
Tclでは、中括弧で囲まれた文字列はリテラルとして扱われますが、引用符で囲まれた文字列はエスケープと補間が行われます。
Perlには、より正式には演算子とみなされるさまざまな文字列があり、これらは引用符演算子および引用符のような演算子として知られています。これらには、通常の構文(固定区切り文字)と、区切り文字を選択できる汎用構文の両方が含まれます。これらには以下が含まれます。[ 26 ]
'' "" `` // m// qr// s/// y // / q{} qq{} qx{} qw{} m{} qr{} s{}{} tr {}{} y {}{}REXX では、文字や文字列を 16 進数または 2 進数コードで指定するために接尾辞文字を使用します。例:
'20' x "0010 0000" b "00100000" b すべてスペース文字を生成し、関数呼び出しを回避しますX2C(20)。
一部の言語では、文字列リテラルに、現在のコンテキスト内の変数や式を参照するプレースホルダーを含めることができ、これらは(通常は実行時に)評価されます。これは変数補間、またはより一般的には文字列補間と呼ばれます。補間をサポートする言語では、一般的に、補間された文字列リテラルとそうでない文字列リテラルを区別します。例えば、sh 互換の Unix シェル(Perl や Ruby も含む) では、二重引用符 (引用符で区切られた " ) で囲まれた文字列は補間されますが、単一引用符 (アポストロフィで区切られた' ) で囲まれた文字列は補間されません。補間されない文字列リテラルは「生文字列」と呼ばれることもありますが、これはエスケープの意味での「生文字列」とは異なります。例えば、Python では、rまたはで始まる文字列Rは生文字列と呼ばれ、エスケープも補間もありません。[ 27 ]通常の文字列 (プレフィックスなし) はエスケープはありますが補間はありません。[ 28 ]fまた、またはで始まる文字列はFf 文字列と呼ばれ[ 29 ] 、エスケープ[ 30 ]と補間があります。[ 31 ]
例えば、以下のPerlコード:
$name = "ナンシー" ; $greeting = "こんにちは世界" ; print "$name は群衆に向かって $greeting と言いました。" ;出力結果:
ナンシーは集まった人々に向かって「ハローワールド」と言った。
この場合、メタ文字($)(変数代入文の記号と混同しないように)は変数補間を示すものとして解釈され、そのまま出力する必要がある場合はエスケープ処理が必要になります。
printfこれは、次のような表記法を使用して同じ出力を生成する関数とは対照的である。
printf "%s は群衆に向かって %s と言いました。" , $name , $greeting ;ただし、補間は実行されません。 はprintf フォーマット文字列%s内のプレースホルダーですが、変数自体は文字列の外にあります。
これは「生の」文字列とは対照的です。
print '$name は群衆に向かって $greeting と言いました。' ;以下のような出力が生成されます。
$nameは群衆に向かって$greetingと言った。
ここでいう「$」文字はメタ文字ではなく、プレーンテキスト以外の意味を持つものとして解釈されることはありません。
文字列リテラルの指定に柔軟性のない言語では、他のプログラミングコードを生成するプログラミングコードを書くのが特に面倒になる。これは、生成言語が出力言語と同じか類似している場合に特に顕著である。
例えば:
しかしながら、一部の言語は、このような自己相似的な出力を生成するのに特に適している。特に、区切り文字の衝突を回避するための複数のオプションをサポートする言語はそうだ。
文字列リテラルをコードとして使用して他のコードを生成すると、特に出力が信頼できないユーザー入力に少なくとも部分的に依存する場合、セキュリティ上の悪影響が生じる可能性があります。これは、Webベースのアプリケーションにおいて特に深刻であり、悪意のあるユーザーがこのような脆弱性を悪用して、例えばSQLインジェクション攻撃を仕掛けるなどして、アプリケーションの動作を妨害する可能性があります。
^文字列リテラルとバイトリテラルはどちらも、オプションで文字
または を接頭辞として付けることができます。このような構造はそれぞれ
生文字列リテラル
と
生バイトリテラル
と呼ばれ
、バックスラッシュはリテラル文字として扱われます。
この資料の他のセクションでは、「生の文字列」という用語が使用されています。'r''R'
'r'、'R'標準 C で使用される規則と同様の規則に従って解釈されます。エスケープ シーケンスは、セクション 2.4.3 f 文字列で説明されているように、「通常の文字列」内でデコードされます。文字
列リテラル
または
f 文字列
は、または
で始まる文字列リテラルです
。
'f''F'