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[1] 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;[2] or substituting into a printf format string, where the variable is far from where it is used. Consider this example in Ruby:
apples=4puts"I have #{apples} apples."# string interpolationputs"I have "+String(apples)+" apples."# string concatenationputs"I have %d apples."%apples# format string
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 $ or %), e.g. $apples or %apples, or with braces, e.g. {apples}, sometimes both, e.g. ${apples}. In some cases, additional formatting specifiers can be used (as in printf), e.g. {apples:3}, and in some cases the formatting specifiers themselves can be interpolated, e.g. {apples:width}. 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:[3]
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.
C does not have interpolated strings, but they can be approximated using sprintf() from <stdio.h>.
#include<stdio.h>#define BUFFER_SIZE 100intmain(){charsentence[BUFFER_SIZE];intage=20;floatheight=5.9;charname[]="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.}
While interpolated strings do not exist in C++, they can be approximated using std::format and std::print functions.
importstd;usingstd::string;intmain(){intapples=4;intbananas=3;std::println("I have {} apples",apples);// format specifiersstd::println("I have {0} fruits, of which there are {1} apples and {2} bananas",apples+bananas,apples,bananas);// specify position explicitly// using std::format():stringname="John Doe";intage=20;stringgreeting=std::format("Hello, {}! You are {} years old.",name,age);}
Interpolated strings have been proposed for inclusion into C++, based on Python f-strings. The proposal incorporates features previously included from std::format, based on {fmt}.[5] In this proposal, each f-string is transformed into a function call to a new function, std::make_formatted_string().
importstd;usingstd::string;usingstd::string_view;intcalculate(intx){// ...}stringrepresent(string_viewprefix,intbits){returnf"{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}";}voiddisplay(string_viewprefix,intbits){std::print(f"{prefix}-{__LINE__}: got {calculate(bits)} for {bits:#06x}");}
While there have been some proposals for string interpolation (which have been rejected),[7][8][9]As of 2025[update] Go does not have interpolated strings.
However, they can be approximated using fmt.Sprintf().
import"fmt"funcmain(){// message is of type stringmessage:=fmt.Sprintf("My name is %s and I am %d years old.","John Doe",20)fmt.Println(message)}
Java had interpolated strings as a preview feature in Java 21 and Java 22. One could use the constant STR of java.lang.StringTemplate directly.
packageorg.wikipedia.examples;enumStage{TEST,QA,PRODUCTION}recordDeploy(UUIDimage,Stagestage){}publicclassExample{publicstaticvoidmain(String[]args){Deploydeploy=newDeploy(UUID.randomUUID(),Stage.TEST)STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..."Deploydeploy=newDeploy(UUID.randomUUID(),Stage.PRODUCTION)STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..."}}
They were removed in Java 23 due to design issues.[12]
Otherwise, interpolated strings can be approximated using the String.format() method.
packageorg.wikipedia.examples;publicclassExample{publicstaticvoidmain(String[]args){intapples=3;intbananas=4;Stringsentence=String.format("I have %d fruits, of which %d are apples and %d are bananas.",apples+bananas,apples,bananas);System.out.println(sentence);Stringname="John Doe";intage=20;System.out.printf("My name is %s, and I am %d years old.",name,age);}}
JavaScript and TypeScript, as of the ECMAScript 2015 (ES6) standard, support string interpolation using backticks ``. This feature is called template literals.[13] Here is an example:
constapples:number=4;constbananas:number=3;console.log(`I have ${apples} apples`);console.log(`I have ${apples+bananas} fruits`);
The output will be:
I have 4 applesI have 7 fruits
Template literals can also be used for multi-line strings:
console.log(`This is the first line of text.This is the second line of text.`);
The output will be:
This is the first line of text.This is the second line of text.
funmain(){valquality:String="superhero"valapples:Int=4valbananas:Int=3valsentence:String="A developer is a $quality. I have ${apples+bananas} fruits"println(sentence)}
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.
importstrutils,strformatvarapples=4varbananas=3echo"I have $1 apples".format(apples)echofmt"I have {apples} apples"echofmt"I have {apples + bananas} fruits"# Multi-lineechofmt"""Ihave{apples}apples"""# Debug the formattingechofmt"I have {apples=} apples"# Custom openChar and closeChar charactersechofmt("I have (apples) {apples}",'(',')')# Backslash inside the formatted string literalechofmt"""{ "yep\nope" }"""
The output will be:
I have 4 applesI have 4 applesI have 7 fruitsI have4 applesI have apples=4 applesI have 4 {apples}yepope
Python supports string interpolation as of version 3.6, referred to as
"formatted string literals" or "f-strings".[14][15][16] Such a literal begins with an f or F before the opening quote, and uses braces for placeholders:
apples:int=4bananas:int=3print(f"I have {apples} apples and {bananas} bananas")
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.[17]
fnmain(){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!():letsentence:String=format!("There are {0} apples and {1} bananas.",apples,bananas);println!(sentence);}
Scala 2.10+ provides a general facility to allow arbitrary processing of a string literal, and supports string interpolation using the included s and f string interpolators. It is also possible to write custom ones or override the standard ones.
The f 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:
valapples=4valbananas=3//before Scala 2.10printf("I have %d apples\n",apples)println("I have %d apples"formatapples)//Scala 2.10+println(s"I have $apples apples")println(s"I have ${apples+bananas} fruits")println(f"I have $apples%d apples")
The output will be:
I have 4 apples
Sciter (tiscript)
In Sciter any function with name starting from $ is considered as interpolating function and so interpolation is customizable and context sensitive:
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.[18] Each item inserted into the string literal is wrapped in a pair of parentheses, prefixed by a backslash.