String interpolation
In computer programming, string interpolation or variable interpolation (also variable substitution or variable expansion) is the process of evaluating a string literal containing one or more placeholders, yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple template processing.[1] or, in formal terms, a form of Quasi-quotation (or logic substitution interpretation). String interpolation allows for easier and more intuitive string formatting and content-specification compared with string concatenation.[2]
String interpolation is common in many programming languages which make heavy use of string representations of data, such as C, Perl, PHP, Python, Ruby, Scala and Swift, and most Unix shells. Two modes of literal expression are usually offered: one with interpolation enabled, the other without ("raw string"). Placeholders are usually represented by a bare or a named sigil, (typically $
or %
), eg. $placeholder
or %123
. Expansion of the string usually occurs at run time
Variations
Some languages do not offer string interpolation, instead offering a standard function where one parameter is the printf format string, and other(s) provide the values for each placeholder.
Ruby uses the "#
" symbol for interpolation, and allows one to interpolate any expression, not just variables. Other languages may support more advanced interpolation with a special formatting function, such as printf
, in which the first argument, the format, specifies the pattern in which the remaining arguments are substituted.
Algorithms
There are two main types of "expand variable" algorithms for variable interpolation:[3]
- Replace and expand placeholders: creating a new string from the original one, by find-replace operations. Find variable-reference (placeholder), replace it by its variable-value. This algorithm offers no cache strategy.
- Split and join string: splitting the string into an array, and merging it with the corresponding array of values; then join items by concatenation. The splitted string can be cached to reuse.
Security issues
String Interpolation, like string concatenation, may lead to security problems. When failed to properly escape or filter user input data, system will expose to SQL injection, script injection, XML External Entity Injection (XXE), and cross-site scripting (XSS) attacks.[4]
An example of SQL injection will be like this:
query = "SELECT x, y, z FROM Table WHERE id='$id'
"
If $id
is replaced with "';
", executing this query will wipe out all the data in Table.
DELETE FROM Table; SELECT * FROM Table WHERE id='
Examples
The following Perl code works identically in PHP:
$name = "Alice";
print "${name} said Hello World to the crowd of people.";
produces the output: Alice said Hello World to the crowd of people.
apples = 4
print("I have $(apples) apples")
# or
print("I have {0} apples" % apples)
The output will be:
I have 4 apples
//Before C# 6.0
apples = 4;
System.Console.WriteLine(String.Format("I have {0} apples", apples));
//C# 6.0
System.Console.WriteLine("(I have \{apples} apples)");
The output will be:
I have 4 apples
Script syntax:
apples = 4;
writeOutput("I have #apples# apples");
Tag syntax:
<cfset apples = 4>
<cfoutput>I have #apples# apples</cfoutput>
The output will be:
I have 4 apples
apples = 4
console.log "I have #{apples} apples"
The output will be:
I have 4 apples
int apples = 4, bananas = 3;
print('I have $apples apples');
print('I have ${apples+bananas} fruits');
The output will be:
I have 4 apples
I have 7 fruits
var apples = 4;
var bananas = 3;
trace('I have $apples apples');
trace('I have ${apples+bananas} fruits');
The output will be:
I have 4 apples
I have 7 fruits
Using strings:
(print (format t "I have ~D apples" 4))
The output will be:
I have 4 apples
We can also generalise this to arbitrary (non-string) LISP expressions, known as s-expressions. The equivalent of string interpolation for s-expressions is quasi-quotation, for example:
(let ((num 4))
(quasiquote (I have (unquote num) apples)))
This results in the s-expression (I have 4 apples), where "I", "have", "4" and "apples" are symbols (i.e. identifiers), rather than strings.
def apples = 4;
def bananas = 3;
Console.WriteLine($"I have $apples apples");
Console.WriteLine($"I have $(apples + bananas) fruits");
You can also use advanced formatting features like this:
def fruits = ["apple", "banana"];
Console.WriteLine($<#I have ..$(fruits; "\n"; f => f + "s")#>);
The output will be:
apples
bananas
my $apples = 4;
print "I have $apples apples\n";
The output will be:
I have 4 apples
<?php
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
class foo {
var $foo;
var $bar;
function foo() {
$this->foo = 'Foo';
$this->bar = array('Bar1', 'Bar2', 'Bar3');
}
}
$foo = new foo();
$name = 'Jason';
echo <<<EOT
My name is "$name". I am printing some $foo->foo.
Now, I am printing some {$foo->bar[1]}.
This should print a capital 'A': \x41
EOT;
?>
The output will be:
My name is "Jason". I am printing some Foo.
Now, I am printing some Bar2.
This should print a capital 'A': A
# in Python 2
apples = 4
print "I have %d apples" % apples
print "I have %(apples)d apples" % locals()
# or in Python 2.6
print "I have {} apples".format(apples)
print "I have {a} apples".format(a=apples)
# or in Python 3
print("I have",apples,"apples",sep=" ")
The output will be:
I have 4 apples
apples = 4
puts "I have #{apples} apples"
# or
puts "I have %s apples" % apples
# or
puts "I have %{a} apples" % {a: apples}
The output will be:
I have 4 apples
Scala 2.10+ has implemented the following string interpolators with compiler macros: s,f and raw. It is even possible to write your own.
The s interpolator
Scala 2.10+'s string Interpolation allows users to embed variable references directly in processed string literals. It's done by the Scala Macro feature. Macros are functions that are called by the compiler during compilation. Here is an example:
val apples = 4
//before Scala 2.10
printf("I have %d apples\n", apples)
//Scala 2.10+
println(s"I have $apples apples")
[8] The output will be:
I have 4 apples
In Swift you can create a new String value from a combination of constants, variables, literals, and expressions by including their values inside a string literal. Each item that you insert into the string literal is wrapped in a pair of parentheses, prefixed by a backslash.
let apples = 4
println("I have \(apples) apples")
The output will be:
I have 4 apples
See also
Notes
- ^ "Enforcing Strict Model-View Separation in Template Engines", T. Parr (2004), WWW2004 conference.
- ^ http://perlmeme.org/howtos/using_perl/interpolation.html
- ^ "smallest-template-system/Simplest algorithms", a online tutorial for placeholder-template-systems.
- ^ http://google-caja.googlecode.com/svn/changes/mikesamuel/string-interpolation-29-Jan-2008/trunk/src/js/com/google/caja/interp/index.html#-autogen-id-1
- ^ http://channel9.msdn.com/Events/Visual-Studio/Connect-event-2014/116
- ^ "[1]", String interpolation in Haxe official manual.
- ^ https://docs.python.org/3/whatsnew/3.0.html
- ^ http://www.horstmann.com/