В компьютерном программировании, интерполяциях строк (или переменной интерполяции, подстановках переменных или переменного расширении) представляет собой процесс оценки в строке буквальной, содержащие один или несколько заполнителей, что дает результат, в котором заполнители заменены соответствующих их значения. Это форма простой обработки шаблона или, формально, форма квазицитирования (или интерпретации логической подстановки ). Интерполяция строк обеспечивает более простое и интуитивно понятное форматирование строк и спецификацию содержимого по сравнению с конкатенацией строк.
Интерполяция строк распространена во многих языках программирования, которые интенсивно используют строковые представления данных, таких как Apache Groovy, Julia, Kotlin, Perl, PHP, Python, Ruby, Scala, Swift, Tcl и большинство оболочек Unix. Обычно предлагаются два режима литерального выражения: один с включенной интерполяцией, другой без (так называемая необработанная строка). Заполнители обычно представлены пустой или именованной сигилой (обычно $
или %
), например, $placeholder
или %123
. Расширение строки обычно происходит во время выполнения.
Некоторые языки не предлагают интерполяцию строк, вместо этого предлагают стандартную функцию, в которой один параметр является строкой формата printf, а другие предоставляют значения для каждого заполнителя.
Ruby использует #
символ для интерполяции и позволяет интерполировать любое выражение, а не только переменные. Другие языки могут поддерживать более продвинутую интерполяцию со специальной функцией форматирования, например printf
, в которой первый аргумент, формат, указывает шаблон, в котором подставляются остальные аргументы.
Существует два основных типа алгоритмов расширения переменных для интерполяции переменных:
Интерполяция строк, как и конкатенация строк, может привести к проблемам с безопасностью. Если вводимые пользователем данные неправильно экранированы или отфильтрованы, система будет подвержена атакам SQL-инъекций, сценариев, XML- инъекций внешних сущностей (XXE) и межсайтовых сценариев (XSS).
Пример SQL-инъекции:
query = "SELECT x, y, z FROM Table WHERE id='$id'
"
Если $id
заменить на " "';
, выполнение этого запроса приведет к удалению всех данных в таблице.DELETE FROM Table; SELECT * FROM Table WHERE id='
Следующий код Perl идентично работает в PHP :
$name = "Alice"; print "${name} said Hello World to the crowd of people.";
производит вывод: Alice said Hello World to the crowd of people.
DATA(apples) = 4. WRITE |I have { apples } apples|.
Результатом будет:
I have 4 apples
apples=4 echo "I have $apples apples" # or echo "I have ${apples} apples"
Результатом будет:
I have 4 apples
apples = 4 print("I have $(apples) apples") # or print("I have {0} apples" % apples)
Результатом будет:
I have 4 apples
var apples = 4; var bananas = 3; Console.WriteLine($"I have {apples} apples"); Console.WriteLine($"I have {apples + bananas} fruits");
Результатом будет:
I have 4 apples I have 7 fruits
Синтаксис скрипта языка разметки ColdFusion (CFML):
apples = 4; writeOutput("I have #apples# apples");
Синтаксис тега:
lt;cfset apples = 4gt; lt;cfoutputgt;I have #apples# appleslt;/cfoutputgt;
Результатом будет:
I have 4 apples
apples = 4 console.log "I have #{apples} apples"
Результатом будет:
I have 4 apples
int apples = 4, bananas = 3; print('I have $apples apples.'); print('I have ${apples+bananas} fruit.');
Результатом будет:
I have 4 apples. I have 7 fruit.
lang:= "Golang" apples:= 3 fmt.Printf("I am a %s developer.\n", lang) fmt.Printf("I have %d apples.\n", apples)
Результатом будет:
I am a Golang developer. I have 3 apples.
В Groovy интерполированные строки известны как GStrings:
def quality = "superhero" final age = 52 def sentence = "A developer is a $quality, if he is ${age lt;= 42 ? "young" : "seasoned"}" println sentence
Результатом будет:
A developer is a superhero if he is seasoned
var apples = 4; var bananas = 3; trace('I have $apples apples.'); trace('I have ${apples+bananas} fruit.');
Результатом будет:
I have 4 apples. I have 7 fruit.
Не имея истинных интерполированных строк, Java использует вспомогательные функции в качестве временного решения.
В версиях Java 5 и выше String.format
для интерполяции можно использовать статический метод:
int apples = 4; int bananas = 3; System.out.println(String.format("I have %s apples and %s bananas", apples, bananas)); System.out.println(String.format("I have %s fruit", apples + bananas));
В Java версии 1.1 и выше MessageFormat
класс может форматировать наборы объектов с помощью заполнителей:
Object[] testArgs = {Long.valueOf(3), "MyDisk"}; MessageFormat form = new MessageFormat( "The disk \"{1}\" contains {0} file(s)."); System.out.println(form.format(testArgs));
JavaScript, как и стандарт ECMAScript 2015 (ES6), поддерживает интерполяцию строк с использованием обратных кавычек ``
. Эта функция называется литералами шаблона. Вот пример:
const apples = 4; const bananas = 3; console.log(`I have ${apples} apples`); console.log(`I have ${apples + bananas} fruit`);
Результатом будет:
I have 4 apples I have 7 fruit
Литералы шаблона также могут использоваться для многострочных строк:
console.log(`This is the first line of text. This is the second line of text.`);
Результатом будет:
This is the first line of text. This is the second line of text.
apples = 4 bananas = 3 print("I have $apples apples and $bananas bananas, making $(apples + bananas) pieces of fruit in total.")
Результатом будет:
I have 4 apples and 3 bananas, making 7 pieces of fruit in total.
val quality = "superhero" val apples = 4 val bananas = 3 val sentence = "A developer is a $quality. I have ${apples + bananas} fruit" println(sentence)
Результатом будет:
A developer is a superhero. I have 7 fruit
def apples = 4; def bananas = 3; Console.WriteLine($"I have $apples apples."); Console.WriteLine($"I have $(apples + bananas) fruit.");
Он также поддерживает расширенные функции форматирования, такие как:
def fruit = ["apple", "banana"]; Console.WriteLine($lt;#I have..$(fruit; "\n"; f =gt; f + "s")#gt;);
Результатом будет:
apples bananas
Тем не ${expr}
менее, рекомендованный синтаксис $var
также поддерживается:
quality = "superhero" apples = 4 bananas = 3 sentence = "A developer is a $quality. I have ${apples + bananas} fruit" echo(sentence)
Результатом будет:
A developer is a superhero. I have 7 fruit
Nim обеспечивает интерполяцию строк через модуль Strutils. Форматированные строковые литералы, вдохновленные F-строкой Python, предоставляются через модуль strformat, макрос strformat проверяет, правильно ли сформирована и типизирована строка форматирования, а затем расширяется в исходный код 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" }"""
Результатом будет:
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
let numberOfApples = "4"; in "I have ${numberOfApples} apples"
Результатом будет:
I have 4 apples
const Apples:= 4 const Bananas:= 3 Println ("I have `(Apples) apples.\n") Println ("I have `(Apples+Bananas) fruit.\n")
Результатом будет:
I have 4 apples. I have 7 fruit.
my $apples = 4; my $bananas = 3; print "I have $apples apples.\n"; print "I have @{[$apples+$bananas]} fruit.\n"; # Uses the Perl array (@) interpolation.
Результатом будет:
I have 4 apples. I have 7 fruit.
lt;?php $apples = 5; $bananas = 3; echo "There are $apples apples and $bananas bananas."; echo "\n"; echo "I have {$apples} apples and {$bananas} bananas.";
Результатом будет:
There are 5 apples and 3 bananas. I have 5 apples and 3 bananas.
# in all versions apples = 4 bananas = 3 print("I have %d apples and %d bananas" % (apples, bananas)) # no longer recommended print("I have %(apples)d apples and %(bananas)d bananas" % locals()) # no longer recommended # with Python 2.6+ print("I have {0} apples and {1} bananas".format(apples, bananas)) print("I have {a} apples and {b} bananas".format(b=bananas, a=apples)) # with Python 2.7+ print("I have {} apples and {} bananas".format(apples, bananas)) # or with Python 3.6+ print(f"I have {apples} apples and {bananas} bananas")
Результатом будет:
I have 4 apples and 3 bananas
apples = 4 puts "I have #{apples} apples" # or puts "I have %s apples" % apples # or puts "I have %{a} apples" % {a: apples}
Результатом будет:
I have 4 apples
Не имея истинных интерполированных строк, Rust предоставляет обходной путь через модуль std:: fmt, с которым взаимодействуют различные макросы, такие как format!, Запись!, и распечатайте!. Эти макросы преобразуются в исходный код Rust во время компиляции, при этом каждый аргумент взаимодействует с модулем форматирования. Средство форматирования поддерживает позиционные параметры, именованные параметры, типы аргументов и определение различных характеристик форматирования.
let (apples, bananas) = (4, 3); println!("There are {} apples and {} bananas.", apples, bananas);
Результатом будет:
There are 4 apples and 3 bananas.
В Scala 2.10+ реализованы следующие строковые интерполяторы: s, f и raw. Также можно написать собственные или заменить стандартные.
Интерполятор f - это макрос компилятора, который перезаписывает строку формата со встроенными выражениями как вызов String.format. Он проверяет, правильно ли сформирована и типизирована строка формата.
Интерполяция строк в Scala 2.10+ позволяет встраивать ссылки на переменные непосредственно в обрабатываемые строковые литералы. Вот пример:
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")
Результатом будет:
I have 4 apples
В Sciter любая функция с именем, начинающимся с $, считается интерполирующей функцией, поэтому интерполяция настраивается и зависит от контекста:
var apples = 4 var bananas = 3 var domElement =...; domElement.$content(lt;pgt;I have {apples} appleslt;/pgt;); domElement.$append(lt;pgt;I have {apples + bananas} fruitslt;/pgt;);
Где
domElement.$content(lt;pgt;I have {apples} appleslt;/pgt;);
компилируется в это:
domElement.html = "lt;pgt;I have " + apples.toHtmlString() + " appleslt;/pgt;";
apples = 4 ; bananas = 3 Output = "I have " apples " apples." Output = "I have " (apples + bananas) " fruit."
Результатом будет:
I have 4 apples. I have 7 fruit.
В Swift новое значение String можно создать из смеси констант, переменных, литералов и выражений, включив их значения в строковый литерал. Каждый элемент, вставленный в строковый литерал, заключен в пару круглых скобок с префиксом обратной косой черты.
let apples = 4 print("I have \(apples) apples")
Результатом будет:
I have 4 apples
Язык команд инструментов всегда поддерживал интерполяцию строк во всех строках, разделенных кавычками.
set apples 4 puts "I have $apples apples."
Результатом будет:
I have 4 apples.
Чтобы фактически отформатировать, а не просто заменить значения, существует функция форматирования.
set apples 4 puts [format "I have %d apples." $apples]
Начиная с версии 1.4 TypeScript поддерживает интерполяцию строк с использованием обратных кавычек ``
. Вот пример:
var apples: number = 4; console.log(`I have ${apples} apples`);
Результатом будет:
I have 4 apples
console.log
Функция может быть использована в качестве printf
функции. Приведенный выше пример можно переписать следующим образом:
var apples: number = 4; console.log("I have %d apples", apples);
Результат остается прежним.
Начиная с Visual Basic 14, в Visual Basic поддерживается строковая интерполяция.
name = "Tom" Console.WriteLine($"Hello, {name}")
напечатает «Привет, Том».