{{short description|Replacing placeholders in a string with values}} In computer programming, '''string interpolation''' (or '''variable interpolation''', '''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<ref>"[https://www.cs.usfca.edu/~parrt/papers/mvc.templates.pdf Enforcing Strict Model-View Separation in Template Engines]", T. Parr (2004), WWW2004 conference.</ref> or, in formal terms, a form of quasi-quotation (or logic substitution interpretation). The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current context.
String interpolation is an alternative to building a string via concatenation, which requires repeat quoting and unquoting;<ref>{{Cite web|url=http://perlmeme.org/howtos/using_perl/interpolation.html|title = Interpolation in Perl |date = 12 December 2024 |quote="This is much tidier than repeat uses of the '.' concatenation operator."}}</ref> or substituting into a printf format string, where the variable is far from where it is used. Consider this example in Ruby: <syntaxhighlight lang="ruby"> apples = 4 puts "I have #{apples} apples." # string interpolation puts "I have " + String(apples) + " apples." # string concatenation puts "I have %d apples." % apples # format string </syntaxhighlight>
Two types of literal expression are usually offered: one with interpolation enabled, the other without. Non-interpolated strings may also escape sequences, in which case they are termed a raw string, though in other cases this is separate, yielding three classes of raw string, non-interpolated (but escaped) string, interpolated (and escaped) string. For example, in Unix shells, single-quoted strings are raw, while double-quoted strings are interpolated. Placeholders are usually represented by a bare or a named sigil (typically <code>$</code> or <code>%</code>), e.g. <code>$apples</code> or <code>%apples</code>, or with braces, e.g. <code>{apples}</code>, sometimes both, e.g. <code>${apples}</code>. In some cases, additional formatting specifiers can be used (as in printf), e.g. <code>{apples:3}</code>, and in some cases the formatting specifiers themselves can be interpolated, e.g. <code>{apples:width}</code>. Expansion of the string usually occurs at run time.
Language support for string interpolation varies widely. Some languages do not offer string interpolation, instead using concatenation, simple formatting functions, or template libraries. String interpolation is common in many programming languages which make heavy use of string representations of data, such as Apache Groovy, Julia, Kotlin, Perl, PHP, Python, Ruby, Scala, Swift, Tcl and most Unix shells.
== Algorithms == There are two main types of variable-expanding algorithms for ''variable interpolation'':<ref>[https://code.google.com/p/smallest-template-system/wiki/SimplestAlgorithm "smallest-template-system/Simplest algorithms"], an online tutorial for placeholder-template-systems.</ref> # ''Replace and expand placeholders'': creating a new string from the original one, by find–replace operations. Find variable reference (placeholder), replace it with its variable value. This algorithm offers no cache strategy. # ''Split and join string'': splitting the string into an array, merging it with the corresponding array of values, then joining items by concatenation. The split string can be cached for reuse.
== Security issues == String interpolation, like string concatenation, may lead to security problems. If user input data is improperly escaped or filtered, the system will be exposed to SQL injection, script injection, XML external entity (XXE) injection, and cross-site scripting (XSS) attacks.<ref>{{cite web |url=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 |title= Secure String Interpolation|website=google-caja.googlecode.com |archive-url=https://web.archive.org/web/20121019065315/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 |archive-date=2012-10-19}}</ref>
An SQL injection example: query = "{{code|2=sql|1=SELECT x, y, z FROM Table WHERE id='$id'}} " If ''<code>$id</code>'' is replaced with ''"<code>'; {{code|2=sql|1=DELETE FROM Table; SELECT * FROM Table WHERE id='}}</code>"'', executing this query will wipe out all the data in <code>Table</code>.
== Examples == === ABAP === {{Main|ABAP}} <syntaxhighlight lang="abap"> DATA(apples) = 4. WRITE |I have { apples } apples|. </syntaxhighlight>The output will be:<syntaxhighlight lang="output"> I have 4 apples </syntaxhighlight>
=== Bash === {{Main|Bash (Unix shell)}} <syntaxhighlight lang="bash"> apples=4 echo "I have $apples apples" # or echo "I have ${apples} apples" </syntaxhighlight> The output will be: <syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== Boo === {{Main|Boo (programming language)}} <syntaxhighlight lang="boo"> apples = 4 print("I have $(apples) apples") # or print("I have {0} apples" % apples) </syntaxhighlight> The output will be: <syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== C === {{Main|C (programming language)}} C does not have interpolated strings, but they can be approximated using <code>sprintf()</code> from <code><stdio.h></code>.
<syntaxhighlight lang="c"> #include <stdio.h>
#define BUFFER_SIZE 100
int main() { char sentence[BUFFER_SIZE];
int age = 20; float height = 5.9; char name[] = "Alice";
sprintf(sentence, "My name is %s and I am %d years old, and I am %.1f feet tall.", name, age, height); printf(sentence); // prints: // My name is Alice, and I am 20 years old, and I am 5.9 feet tall. } </syntaxhighlight>
=== C++ === {{Main|C++}} While interpolated strings do not exist in C++, they can be approximated using <code>std::format</code> and <code>std::print</code> functions. <syntaxhighlight lang="cpp"> import std;
using std::string;
int main() { int apples = 4; int bananas = 3;
std::println("I have {} apples", apples); // format specifiers std::println("I have {0} fruits, of which there are {1} apples and {2} bananas", apples + bananas, apples, bananas); // specify position explicitly
// using std::format(): string name = "John Doe"; int age = 20; string greeting = std::format("Hello, {}! You are {} years old.", name, age); } </syntaxhighlight>
Interpolated strings have been proposed for inclusion into C++, based on Python f-strings. The proposal incorporates features previously included from <code>std::format</code>, based on ''{fmt}''.<ref>{{Cite web|title=String interpolation - p3412r0|url=https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2024/p3412r0.pdf|author=Bengt Gustafsson, Victor Zverovich|website=open-std.org|publisher=WG 21|date=14 October 2024}}</ref> In this proposal, each f-string is transformed into a function call to a new function, <code>std::make_formatted_string()</code>. <syntaxhighlight lang=cpp> import std;
using std::string; using std::string_view;
int calculate(int x) { // ... }
string represent(string_view prefix, int bits) { return f"{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}"; }
void display(string_view prefix, int bits) { std::print(f"{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}"); } </syntaxhighlight>
=== C# === {{Main|C Sharp (programming language)}} <syntaxhighlight lang="csharp"> int apples = 4; int bananas = 3;
Console.WriteLine($"I have {apples} apples"); Console.WriteLine($"I have {apples + bananas} fruits"); </syntaxhighlight> <ref>{{Cite web|url=https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/strings/#string-interpolation|title = Strings - C# Programming Guide| date=15 March 2024 }}</ref>
The output will be: <syntaxhighlight lang="output"> I have 4 apples I have 7 fruits </syntaxhighlight>
This can also be done using <code>String.Format()</code>. <syntaxhighlight lang="csharp"> int apples = 4; int bananas = 3;
Console.WriteLine(String.Format("I have {0} apples and {1} bananas.", apples, bananas)); </syntaxhighlight>
=== ColdFusion Markup Language === {{Main|ColdFusion Markup Language}}
ColdFusion Markup Language (CFML) script syntax: <syntaxhighlight lang="cfc"> apples = 4; writeOutput("I have #apples# apples");</syntaxhighlight>
Tag syntax: <syntaxhighlight lang="cfm"> <cfset apples = 4> <cfoutput>I have #apples# apples</cfoutput></syntaxhighlight>
The output will be: {{samp|I have 4 apples}}
=== CoffeeScript === {{Main|CoffeeScript}} <syntaxhighlight lang="coffeescript"> apples = 4 console.log "I have #{apples} apples" </syntaxhighlight> The output will be: <syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== Dart === {{Main|Dart (programming language)}} <syntaxhighlight lang="dart"> int apples = 4, bananas = 3; print('I have $apples apples.'); print('I have ${apples+bananas} fruits.'); </syntaxhighlight> The output will be: <syntaxhighlight lang="output">I have 4 apples. I have 7 fruits.</syntaxhighlight>
=== Go === {{Main|Go (programming language)}} While there have been some proposals for string interpolation (which have been rejected),<ref>{{cite web|url=https://github.com/golang/go/issues/34174 |title=proposal: Go 2: string interpolation #34174|website=GitHub }}</ref><ref>{{cite web|url=https://github.com/golang/go/issues/50554 |title=proposal: Go 2: string interpolation evaluating to string and list of expressions #50554|website=GitHub }}</ref><ref>{{Cite web |title=proposal: spec: add simple string interpolation similar to Swift · Issue #57616 · golang/go |url=https://github.com/golang/go/issues/57616 |access-date=2025-05-19 |website=GitHub |language=en}}</ref> {{as of|2025}} Go does not have interpolated strings.
However, they can be approximated using <code>fmt.Sprintf()</code>. <syntaxhighlight lang="go"> import "fmt"
func main() { // message is of type string message := fmt.Sprintf("My name is %s and I am %d years old.", "John Doe", 20) fmt.Println(message) } </syntaxhighlight>
=== Groovy === {{Main|Groovy (programming language)}} In groovy, interpolated strings are known as GStrings:<ref>{{Cite web|title=The Apache Groovy programming language - Syntax|url=https://groovy-lang.org/syntax.html#_string_interpolation|access-date=2021-06-20|website=groovy-lang.org}}</ref> <syntaxhighlight lang="groovy"> def quality = "superhero" final age = 52 def sentence = "A developer is a $quality if he is ${age <= 42 ? 'young' : 'seasoned'}" println sentence </syntaxhighlight> The output will be: <syntaxhighlight lang="output">A developer is a superhero if he is seasoned</syntaxhighlight>
=== Haxe === {{Main|Haxe}} <syntaxhighlight lang="haxe"> var apples = 4; var bananas = 3; trace('I have $apples apples.'); trace('I have ${apples+bananas} fruits.'); </syntaxhighlight> The output will be:<ref>{{Cite news|url=https://haxe.org/manual/lf-string-interpolation.html|title=Haxe - Manual - String interpolation|work=Haxe - The Cross-platform Toolkit|access-date=2017-09-12}}</ref> <syntaxhighlight lang="output"> I have 4 apples. I have 7 fruits. </syntaxhighlight>
=== Java === {{Main|Java (programming language)}}
Java had interpolated strings as a preview feature in Java 21 and Java 22. One could use the constant STR of [https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/StringTemplate.html java.lang.StringTemplate] directly. <syntaxhighlight lang="java"> package org.wikipedia.examples;
enum Stage { TEST, QA, PRODUCTION }
record Deploy(UUID image, Stage stage) {}
public class Example { public static void main(String[] args) { Deploy deploy = new Deploy(UUID.randomUUID(), Stage.TEST) STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..." Deploy deploy = new Deploy(UUID.randomUUID(), Stage.PRODUCTION) STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..." } } </syntaxhighlight>
They were removed in Java 23 due to design issues.<ref>{{cite web | title=Significant Changes in the JDK | url=https://docs.oracle.com/en/java/javase/23/migrate/significant-changes-jdk-release.html }}</ref>
Otherwise, interpolated strings can be approximated using the <code>String.format()</code> method. <syntaxhighlight lang="java"> package org.wikipedia.examples;
public class Example { public static void main(String[] args) { int apples = 3; int bananas = 4;
String sentence = String.format("I have %d fruits, of which %d are apples and %d are bananas.", apples + bananas, apples, bananas); System.out.println(sentence);
String name = "John Doe"; int age = 20; System.out.printf("My name is %s, and I am %d years old.", name, age); } } </syntaxhighlight>
=== JavaScript/TypeScript === {{Main|JavaScript|TypeScript}} JavaScript and TypeScript, as of the ECMAScript 2015 (ES6) standard, support string interpolation using backticks <code>``</code>. This feature is called ''template literals''.<ref>{{Cite web|url=https://developer.mozilla.org/docs/Web/JavaScript/Reference/Template_literals|title = Template literals (Template strings) - JavaScript | MDN| date=31 May 2024 }}</ref> Here is an example: <syntaxhighlight lang="typescript"> const apples: number = 4; const bananas: number = 3; console.log(`I have ${apples} apples`); console.log(`I have ${apples + bananas} fruits`); </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples I have 7 fruits </syntaxhighlight>
Template literals can also be used for multi-line strings: <syntaxhighlight lang="javascript"> console.log(`This is the first line of text. This is the second line of text.`); </syntaxhighlight>
The output will be: <syntaxhighlight lang="output"> This is the first line of text. This is the second line of text. </syntaxhighlight>
=== Julia === {{Main|Julia (programming language)}} <syntaxhighlight lang="julia"> apples = 4 bananas = 3 print("I have $apples apples and $bananas bananas, making $(apples + bananas) pieces of fruit in total.") </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples and 3 bananas, making 7 pieces of fruit in total. </syntaxhighlight>
=== Kotlin === {{Main|Kotlin (programming language)}} <syntaxhighlight lang="kotlin"> fun main() { val quality: String = "superhero" val apples: Int = 4 val bananas: Int = 3 val sentence: String = "A developer is a $quality. I have ${apples + bananas} fruits" println(sentence) } </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> A developer is a superhero. I have 7 fruits </syntaxhighlight>
=== Nemerle === {{Main|Nemerle}} <syntaxhighlight lang="boo"> def apples = 4; def bananas = 3; Console.WriteLine($"I have $apples apples."); Console.WriteLine($"I have $(apples + bananas) fruit.");</syntaxhighlight> It also supports advanced formatting features, such as: <syntaxhighlight lang="boo">def fruit = ["apple", "banana"]; Console.WriteLine($<#I have ..$(fruit; "\n"; f => f + "s")#>);</syntaxhighlight> The output will be: <syntaxhighlight lang="output">apples bananas</syntaxhighlight>
=== Nim === {{Main|Nim (programming language)}} Nim provides string interpolation via the strutils module. Formatted string literals inspired by Python F-string are provided via the strformat module, the strformat macro verifies that the format string is well-formed and well-typed, and then are expanded into Nim source code at compile-time. <syntaxhighlight lang="nim"> import strutils, strformat var apples = 4 var bananas = 3 echo "I have $1 apples".format(apples) echo fmt"I have {apples} apples" echo fmt"I have {apples + bananas} fruits"
# Multi-line echo fmt""" I have {apples} apples"""
# Debug the formatting echo fmt"I have {apples=} apples"
# Custom openChar and closeChar characters echo fmt("I have (apples) {apples}", '(', ')')
# Backslash inside the formatted string literal echo fmt"""{ "yep\nope" }""" </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples I have 4 apples I have 7 fruits I have 4 apples I have apples=4 apples I have 4 {apples} yep ope </syntaxhighlight>
=== Nix === {{Main|Nix package manager}} <syntaxhighlight lang="nix"> let numberOfApples = "4"; in "I have ${numberOfApples} apples" </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples </syntaxhighlight>
=== ParaSail === {{Main|ParaSail (programming language)}} <syntaxhighlight lang="parasail"> const Apples := 4 const Bananas := 3 Println ("I have `(Apples) apples.\n") Println ("I have `(Apples+Bananas) fruits.\n") </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples. I have 7 fruits. </syntaxhighlight>
=== Perl === {{Main|Perl}} <syntaxhighlight lang="perl"> my $apples = 4; my $bananas = 3; print "I have $apples apples.\n"; print "I have @{[$apples+$bananas]} fruit.\n"; # Uses the Perl array (@) interpolation. </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples. I have 7 fruit.</syntaxhighlight>
=== PHP === {{Main|PHP}} <syntaxhighlight lang="php"> <?php $apples = 5; $bananas = 3; echo "There are $apples apples and $bananas bananas.\n"; echo "I have {$apples} apples and {$bananas} bananas."; </syntaxhighlight>The output will be: <syntaxhighlight lang="output">There are 5 apples and 3 bananas. I have 5 apples and 3 bananas.</syntaxhighlight>
=== Python === {{Main|Python (programming language)}} Python supports string interpolation as of version 3.6, referred to as "formatted string literals" or "f-strings".<ref>{{cite web |url=https://docs.python.org/3/tutorial/inputoutput.html#tut-f-strings |title= The Python Tutorial: 7.1.1. Formatted String Literals}}</ref><ref>{{Cite web |url=https://docs.python.org/3/reference/lexical_analysis.html#f-strings |title=The Python Language Reference: 2.4.3. Formatted string literals}}</ref><ref>{{Cite web|url=https://www.python.org/dev/peps/pep-0498/|title = PEP 498 -- Literal String Interpolation}}</ref> Such a literal begins with an <code>f</code> or <code>F</code> before the opening quote, and uses braces for placeholders: <syntaxhighlight lang="python"> apples: int = 4 bananas: int = 3
print(f"I have {apples} apples and {bananas} bananas") </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples and 3 bananas</syntaxhighlight>
=== Ruby/Crystal === {{Main|Ruby (programming language)|Crystal (programming language)}} <syntaxhighlight lang="ruby"> apples = 4 puts "I have #{apples} apples" # Format string applications for comparison: puts "I have %s apples" % apples puts "I have %{a} apples" % {a: apples} </syntaxhighlight>
The output will be: <syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== Rust === {{Main|Rust (programming language)}}
Rust does not have general string interpolation, but provides similar functionality via macros, referred to as "Captured identifiers in format strings", introduced in version 1.58.0, released 2022-01-13.<ref>{{cite web |url=https://blog.rust-lang.org/2022/01/13/Rust-1.58.0.html#captured-identifiers-in-format-strings |title=Announcing Rust 1.58.0: Captured identifiers in format strings |date=2022-01-13}}</ref>
Rust provides formatting via the [https://doc.rust-lang.org/stable/std/fmt/ std::fmt] module, which is interfaced with through various macros such as [https://doc.rust-lang.org/stable/std/macro.format.html format!], [https://doc.rust-lang.org/stable/std/macro.write.html write!], and [https://doc.rust-lang.org/stable/std/macro.print.html print!]. These macros are converted into Rust source code at compile-time, whereby each argument interacts with a [https://doc.rust-lang.org/nightly/std/fmt/struct.Formatter.html formatter]. The formatter supports [https://doc.rust-lang.org/stable/std/fmt/#positional-parameters positional parameters], [https://doc.rust-lang.org/stable/std/fmt/#named-parameters named parameters], [https://doc.rust-lang.org/stable/std/fmt/#argument-types argument types], defining various [https://doc.rust-lang.org/stable/std/fmt/#formatting-traits formatting traits], and capturing identifiers from the environment.
<syntaxhighlight lang="rust"> fn main() { let (apples, bananas): (i32, i32) = (4, 3); // println! captures the identifiers when formatting: the string itself isn't interpolated by Rust. println!("There are {apples} apples and {bananas} bananas.");
// alternatively, with format!(): let sentence: String = format!("There are {0} apples and {1} bananas.", apples, bananas); println!(sentence); } </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> There are 4 apples and 3 bananas. </syntaxhighlight>
=== Scala === {{Main|Scala (programming language)}}
Scala 2.10+ provides a general facility to allow arbitrary processing of a string literal, and supports string interpolation using the included <code>s</code> and <code>f</code> string interpolators. It is also possible to write custom ones or override the standard ones.
The <code>f</code> interpolator is a compiler macro that rewrites a format string with embedded expressions as an invocation of String.format. It verifies that the format string is well-formed and well-typed.
==== The standard interpolators ==== Scala 2.10+'s string interpolation allows embedding variable references directly in processed string literals. Here is an example: <syntaxhighlight lang="scala"> val apples = 4 val bananas = 3 //before Scala 2.10 printf("I have %d apples\n", apples) println("I have %d apples" format apples) //Scala 2.10+ println(s"I have $apples apples") println(s"I have ${apples + bananas} fruits") println(f"I have $apples%d apples") </syntaxhighlight>
The output will be:<syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== Sciter (tiscript) === In Sciter any function with name starting from $ is considered as interpolating function and so interpolation is customizable and context sensitive: <syntaxhighlight lang="javascript"> var apples = 4 var bananas = 3 var domElement = ...;
domElement.$content(<p>I have {apples} apples</p>); domElement.$append(<p>I have {apples + bananas} fruits</p>); </syntaxhighlight>
Where <syntaxhighlight lang="javascript">domElement.$content(<p>I have {apples} apples</p>);</syntaxhighlight> gets compiled to this: <syntaxhighlight lang="javascript">domElement.html = "<p>I have " + apples.toHtmlString() + " apples</p>";</syntaxhighlight>
=== Snobol === {{Main|SNOBOL}} <syntaxhighlight lang="snobol"> apples = 4 ; bananas = 3 Output = "I have " apples " apples." Output = "I have " (apples + bananas) " fruits." </syntaxhighlight> The output will be: <syntaxhighlight lang="output"> I have 4 apples. I have 7 fruits. </syntaxhighlight>
=== Swift=== {{Main|Swift (programming language)}}
In Swift, a new String value can be created from a mix of constants, variables, literals, and expressions by including their values inside a string literal.<ref>{{Cite web|title=Strings and Characters — The Swift Programming Language (Swift 5.5)|url=https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html|access-date=2021-06-20|website=docs.swift.org}}</ref> Each item inserted into the string literal is wrapped in a pair of parentheses, prefixed by a backslash.
<syntaxhighlight lang="fsharp"> let apples = 4 print("I have \(apples) apples") </syntaxhighlight>The output will be: <syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== Tcl === {{Main|Tcl (programming language)}}
The Tool Command Language has always supported string interpolation in all quote-delimited strings.
<syntaxhighlight lang="tcl"> set apples 4 puts "I have $apples apples." </syntaxhighlight> The output will be: <syntaxhighlight lang="output">I have 4 apples.</syntaxhighlight>
In order to actually format – and not simply replace – the values, there is a formatting function.
<syntaxhighlight lang="tcl"> set apples 4 puts [format "I have %d apples." $apples] </syntaxhighlight>
=== Visual Basic .NET === As of Visual Basic 14, string interpolation is supported in Visual Basic.<ref>{{Cite web|last=KathleenDollard|title=Interpolated Strings - Visual Basic|url=https://docs.microsoft.com/en-us/dotnet/visual-basic/programming-guide/language-features/strings/interpolated-strings|access-date=2021-06-20|website=docs.microsoft.com|language=en-us}}</ref> <syntaxhighlight lang="vbnet"> name = "Tom" Console.WriteLine($"Hello, {name}") </syntaxhighlight>
The output will be: {{sxhl|Hello, Tom|output}}
== See also == * Concatenation * Improper input validation * printf format string * Quasi-quotation * String literal * Substitution
== Notes == {{Reflist}}
Category:Programming constructs Interpolation Category:Variable (computer science)