文字列補間

プログラミングにおいて、文字列補間とは、文字列リテラル内に埋め込まれたプレースホルダーを実行時に評価し、そのプレースホルダーを対応する値に置き換える処理である。変数補間 、変数置換、変数展開ともいう。この処理は、単純なテンプレートエンジンであり、正式な用語で言えば準引用の一形態である。文字列補間は、文字列連結よりも簡単でより直観的に文字列のフォーマットを規定できる。

文字列補間は、データの文字列表現を多用する多くのプログラミング言語で使用できる。

文字列リテラルの表現には、文字列補間が使えるものと、使えないものがある。プレースホルダーは、無名もしくは名前のついたシギル で示される。一般的には$や%が使用され、名前つきの場合は$placeholderや%123のようになる。文字列の補間は実行時に行われる。

1. 変種
-----

いくつかの言語は文字列補間に対応していない。例えばC言語のprintf関数では、第1引数が書式化文字列であり、第2引数以降に書式化文字列内のプレースホルダーを置き換える定数・変数や式が置かれる。

Rubyでは"#"を補間のための記号として使用するが、変数だけでなくどんな式でも補間できる。他の言語では、printfのような特別なフォーマット用の関数でより進んだ補間法に対応しているものもある。その場合、第1引数で第2引数以降が代えられるパターンを指定する。

2. アルゴリズム
---------

文字列補間のための変数を展開するアルゴリズムには、主に2つの方法がある

プレースホルダーの置換と展開  : オリジナルの文字列を元にして、検索置換  演算によって新しい文字列を作成する。プレイスホルダーを見つけたら、それを変数の値に置き換える。このアルゴリズムは、キャッシュが使用できない。
文字列の分割と結合  : 文字列を配列に分割する。そして、それを対応する値の配列に合併し、最後に、全ての配列を結合する。分割した文字列は、再理用のためにキャッシュしておくことができる。

3. セキュリティ上の問題
-------------

文字列連結と同様、文字列補間はセキュリティ上の問題を招く可能性がある。プログラマがきちんとユーザー入力データをエスケープするかフィルターに通すかしないならば、システムはSQLインジェクション、スクリプトインジェクション、XML外部エンティティインジェクション 、クロスサイトスクリプティング  などの攻撃にさらされることになる。

以下は、SQLインジェクションを引き起こす文字列補間の例である。 query = "2=sql " ここで、//$id//が//"'; 2=sql"//に補間された場合、このクエリを実行するとテーブルの全てのデータが削除されてしまう。

4. 例
----

以下のPerlのコードは、PHPでも同じように動作する。 $name = "Alice"; print "${name} said Hello World to the crowd of people."; このコードは、Alice said Hello World to the crowd of people.と出力する。

4.1. Boo
--------

apples = 4 print apples")

またはprint<WtXmlEndTag /> 上記のコードは以下のように出力する。I have 4 apples

4.2. C#.NET
-----------

var apples = 4; // Before C# 6.0 System.Console.WriteLine); // Before C# 6.0 WriteLineメソッド自体が書式指定に対応しているため、簡潔にこう書ける。 System.Console.WriteLine; // C# 6.0 System.Console.WriteLine;

上記のコードは以下のように出力する。I have 4 apples

4.3. CFML
---------

Script syntax: apples = 4; writeOutput;

Tag syntax:I have #apples# apples

上記のコードは以下のように出力する。

4.4. CoffeeScript
-----------------

apples = 4 console.log "I have #{apples} apples" 上記のコードは以下のように出力する。I have 4 apples

4.5. Dart
---------

int apples = 4, bananas = 3; print; print; 上記のコードは以下のように出力する。I have 4 apples. I have 7 fruit.

4.6. Groovy
-----------

def quality = 'superhero' def sentence = "A developer is a ${quality}" print sentence 上記のコードは以下のように出力する。A developer is a superhero

4.7. Haxe
---------

var apples = 4; var bananas = 3; trace; trace; 上記のコードは以下のように出力する。I have 4 apples. I have 7 fruit.

4.8. Nemerle
------------

def apples = 4; def bananas = 3; Console.WriteLine; Console.WriteLine fruit."); 上記のコードは以下のようにも書ける。def fruit = ["apple", "banana"]; Console.WriteLine#>); 上記のコードは以下のように出力する。apples bananas

4.9. Perl
---------

my $apples = 4; my $bananas = 3; print "I have $apples apples. "; print "I have @{[$apples+$bananas]} fruit. "; # Uses the Perl array  interpolation. 上記のコードは以下のように出力する。 I have 4 apples. I have 7 fruit.

4.10. PHP
---------

<?php class foo { var $foo; var $bar; function foo { $this->foo = 'Foo'; $this->bar = array; } } $foo = new foo; $name = 'Jason'; echo <<foo. Now, I am printing some {$foo->bar[1]}. This should print a capital 'A': \x41 EOT; ?>上記のコードは以下のように出力する。My name is "Jason". I am printing some Foo. Now, I am printing some Bar2. This should print a capital 'A': A

4.11. Python
------------

in Python 2apples = 4 print "I have %d apples" % apples print "I have %d apples" % locals

or in Python 2.6print "I have {} apples".format print "I have {a} apples".format

or in Python 3print))

or with Python 3.6print<WtXmlEndTag /> 上記のコードは以下のように出力する。 I have 4 apples

4.12. Ruby
----------

apples = 4 puts "I have #{apples} apples"

orputs "I have %s apples" % apples

orputs "I have %{a} apples" % {a: apples}<WtXmlEndTag />

上記のコードは以下のように出力する。I have 4 apples

4.13. Scala
-----------

Scala 2.10以降には、s, f, rawの3つの文字列補間子が実装されている。

f補間子はString.formatを呼び出すための組み込み表現で、書式付き文字列を書き直すコンパイラ・マクロである。

val apples = 4 //before Scala 2.10 printf println //Scala 2.10+ println println 上記のコードは以下のように出力する。I have 4 apples

4.14. Swift
-----------

Swiftでは、定数・変数・リテラル・式の組合せから、それらの値を文字列リテラルの中に含むことによって、新しい文字列の値を作ることができる。文字列リテラルに含むそれぞれのアイテムは、一対の括弧で囲まれ、その前にバックスラッシュが置かれる。

let apples = 4 print apples")上記のコードは以下のように出力する。I have 4 apples

4.15. TypeScript
----------------

バージョン1.4より、TypeScriptはバッククォート `` を使用した文字列補間に対応した。以下はその例である。 var apples: number = 4; console.log; 上記のコードは以下のように出力する。I have 4 applesconsole.log関数はprintf関数と同じように使用できる。上記の列は、以下のようにも書き表せる。 var apples: number = 4; console.log;

5. 関連項目
-------

文字列連結
printf

6. 出典
-----