Content deleted Content added
remove REXX - an example of substitution not interpolation Tag: section blanking |
Citation bot (talk | contribs) Add: title, date. Changed bare reference to CS1/2. | Use this bot. Report bugs. | Suggested by Folkezoft | Linked from User:Folkezoft/sandbox | #UCB_webform_linked 829/978 |
||
(244 intermediate revisions by more than 100 users not shown) | |||
Line 1:
{{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 [[Form (document)#Placeholders|placeholders]], yielding a result in which the placeholders are replaced with their corresponding values. It is a form of simple [[Template processor|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 (logic)|substitution]] interpretation). The placeholder may be a variable name, or in some languages an arbitrary expression, in either case evaluated in the current [[Scope (computer science)|context]].
String interpolation is an alternative to building 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. Compare:
<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 sequence]]s, 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 (computer programming)|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 (program lifecycle phase)|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 language]]s which make heavy use of [[String (computer science)|string]] representations of data, such as [[Groovy (programming language)|Apache Groovy]], [[Julia (programming language)|Julia]], [[Kotlin (programming language)|Kotlin]], [[Perl]], [[PHP]], [[Python (programming language)|Python]], [[Ruby (programming language)|Ruby]], [[Scala (programming language)|Scala]], [[Swift (programming language)|Swift]], [[Tcl]] and most [[Unix shell]]s.
== 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 by 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 attack|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>.
=== 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>
===
{{Main|Bash (Unix shell)}}
<syntaxhighlight lang="bash">
apples=4
echo "I have $apples apples"
# or
</syntaxhighlight>
The output will be:
<syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
===
{{Main|Boo (programming language)}}
<syntaxhighlight lang="boo">
apples = 4
print("I have $(apples) apples")
print("I have {0} apples" % apples)
</syntaxhighlight>
The output will be:
<syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
=== C# ===
{{Main|C Sharp (programming language)}}
<syntaxhighlight lang="csharp">
var apples = 4;
var 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:
<
I have 4 apples
I have 7 fruits
</syntaxhighlight>
=== ColdFusion Markup Language ===
{{Main article|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:
<
I have
===
{{Main|Go (programming language)}}
{{as of|2025}}, Go does not have string interpolation. 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>
=== 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>
===
{{Main|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 article|Java (programming language)}}
Java had interpolated strings as a preview feature in Java 21 and Java 22. You 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" line="1">
enum Stage{test,qa,prod}
record Deploy(UUID image, Stage stage){}
var deploy=new Deploy(UUID.randomUUID(), Stage.test)
STR."Installing \{deploy.image()} on Stage \{deploy.stage()} ..."
var deploy=new Deploy(UUID.randomUUID(), Stage.prod)
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>
=== JavaScript ===
{{Main article|JavaScript}}
[[JavaScript]], as of the [[ECMAScript]] 2015 (ES6) standard, supports 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="javascript">
const apples = 4;
const bananas = 3;
console.log(`I have ${apples} apples`);
console.log(`I have ${apples + bananas} fruits`);
</syntaxhighlight>
The output will be:
<
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>
===
{{Main|Kotlin (programming language)}}
<syntaxhighlight lang="kotlin">
val quality = "superhero"
val apples = 4
val bananas = 3
val sentence = "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:
<
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">
num_apples = 4
num_bananas = 3
print(f'I have {num_apples} apples and {num_bananas} bananas')
</syntaxhighlight>
The output will be:
<syntaxhighlight lang="output">
I have 4 apples and 3 bananas</syntaxhighlight>
=== Ruby / Crystal ===
{{Main|Ruby (programming language)}}
{{Main|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 article|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">
let (apples, bananas) = (4, 3);
// println! captures the identifiers when formatting: the string itself isn't interpolated by Rust.
println!("There are {apples} apples and {bananas} bananas.");
</syntaxhighlight>
The output will be:
<syntaxhighlight lang="output">
There are 4 apples and 3 bananas.
</syntaxhighlight>
=== Scala ===
{{Main article|Scala (programming language)}}
[[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 article|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 article|Swift (programming language)}}
In [[Swift (programming language)|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 article|Tcl}}
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>
=== TypeScript ===
{{Main article|TypeScript}}
As of version 1.4, [[TypeScript]] supports string interpolation using backticks <code>``</code>. Here is an example:
<syntaxhighlight lang="typescript">
var apples: number = 4;
console.log(`I have ${apples} apples`);
</syntaxhighlight>
The output will be:
<syntaxhighlight lang="output">I have 4 apples</syntaxhighlight>
The <code>console.log</code> function can be used as a <code>printf</code> function. The above example can be rewritten, thusly:
<syntaxhighlight lang="typescript">
var apples: number = 4;
console.log("I have %d apples", apples);
</syntaxhighlight>
The output remains the same.
===
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>
{{sxhl|Hello, Tom|output}}
== See also ==
* [[
* [[Improper input validation]]
* [[
* [[Quasi-quotation]]
* [[String literal]]
* [[Substitution (logic)|Substitution]]
== Notes ==
Line 155 ⟶ 477:
[[Category:Programming constructs]]
[[Category:String (computer science)|Interpolation]]
[[Category:Variable (computer science)]]
|