В компьютерном программировании строковая интерполяция (или интерполяция переменных , замена переменных или расширение переменных ) — это процесс оценки строкового литерала , содержащего один или несколько заполнителей , дающий результат, в котором заполнители заменяются соответствующими значениями. Это форма простой обработки шаблонов [1] или, формально говоря, форма квазицитирования (или интерпретации логической подстановки ). Заполнителем может быть имя переменной или, в некоторых языках, произвольное выражение, в любом случае оцениваемое в текущем контексте .
Интерполяция строк — это альтернатива построению строки посредством конкатенации , которая требует повторного заключения и удаления кавычек; [2] или подстановкой в строку формата printf , где переменная находится далеко от того места, где она используется. Сравнивать:
apples = 4 означает «У меня # { apples } яблок». # строковая интерполяция помещает "У меня есть " + String ( apples ) + " apples." # Конкатенация строк приводит к выводу : «У меня есть %d яблок». % яблок # строка формата
Обычно предлагаются два типа буквального выражения: один с включенной интерполяцией, другой без. Неинтерполированные строки также могут экранировать последовательности , и в этом случае они называются необработанной строкой , хотя в других случаях это отдельно, что дает три класса необработанной строки, неинтерполированной (но экранированной) строки, интерполированной (и экранированной) строки. Например, в оболочках Unix строки в одинарных кавычках являются необработанными, а строки в двойных кавычках интерполируются. Заполнители обычно представляют собой простой или именованный символ (обычно $
или %
), например $apples
или %apples
, или фигурные скобки, например {apples}
, а иногда и то, и другое, например ${apples}
. В некоторых случаях могут использоваться дополнительные спецификаторы форматирования (как в printf), например {apples:3}
, а в некоторых случаях сами спецификаторы форматирования могут быть интерполированы, например {apples:width}
. Расширение строки обычно происходит во время выполнения .
Языковая поддержка интерполяции строк сильно различается. Некоторые языки не поддерживают интерполяцию строк, вместо этого используются конкатенация, простые функции форматирования или библиотеки шаблонов. Строковая интерполяция распространена во многих языках программирования , которые интенсивно используют строковые представления данных, таких как Apache Groovy , Julia , Kotlin , Perl , PHP , Python , Ruby , Scala , Swift , Tcl и большинство оболочек Unix .
Существует два основных типа алгоритмов расширения переменных для интерполяции переменных : [3]
Интерполяция строк, как и конкатенация строк, может привести к проблемам безопасности. Если вводимые пользователем данные неправильно экранируются или фильтруются, система будет подвержена атакам SQL-инъекций , скриптов , внедрения внешних объектов XML (XXE) и межсайтовых скриптов (XSS). [4]
Пример SQL-инъекции:
запрос = " "SELECT x, y, z FROM Table WHERE id='$id'
Если $id
заменить на " "';
, выполнение этого запроса приведет к удалению всех данных в файле DELETE FROM Table; SELECT * FROM Table WHERE id='
Table
.
ДАННЫЕ ( яблоки ) = 4 . НАПИСАТЬ | У меня есть { яблоки } яблоки |.
Результатом будет:
у меня 4 яблока
apples = 4 echo "У меня есть $apples яблок" # или echo "У меня есть ${ apples } яблок"
Результатом будет:
у меня 4 яблока
apples = 4 print ( «У меня есть $(apples) apples» ) # или print ( «У меня есть {0} яблок» % apples )
Результатом будет:
у меня 4 яблока
вар яблоки = 4 ; вар бананы = 3 ; Консоль . WriteLine ( $"У меня есть {apples} яблок" ); Консоль . WriteLine ( $"У меня есть фрукты {яблоки + бананы}" );
[5]
Результатом будет:
У меня есть 4 яблока, у меня 7 фруктов.
Синтаксис сценария языка разметки ColdFusion (CFML):
яблоки = 4 ; writeOutput ( "У меня есть #apples# яблоки" );
Синтаксис тега:
<cfset apples = 4 > <cfoutput> У меня # яблок # яблок </cfoutput>
Результатом будет:
у меня 4 яблока
яблоки = 4 консоли . log "У меня #{ apples } яблок"
Результатом будет:
у меня 4 яблока
int яблоки = 4 , бананы = 3 ; print ( 'У меня есть $ apples apples.' ); print ( 'У меня есть ${ яблоки + бананы } фруктов.' );
Результатом будет:
У меня есть 4 яблока. У меня есть 7 фруктов.
По состоянию на 2022 год [обновлять]в Go нет интерполяции строк. Было несколько предложений по интерполяции строк в следующей версии языка, Go 2. [6] [7] Вместо этого Go использует строки формата printf в fmt.Sprintf
функциях, конкатенацию строк или библиотеки шаблонов, такие как text/template
.
В groovy интерполированные строки известны как GStrings: [8]
def качество = "супергерой" окончательный возраст = 52 def предложение = "Разработчик является $качеством, если он ${возраст <= 42? 'молодой': 'опытный'}" println предложение
Результатом будет:
Разработчик — супергерой, если он опытный
вар яблоки = 4 ; вар бананы = 3 ; трассировка ( 'У меня есть $ apples apples.' ); трассировка ( 'У меня есть ${ яблоки + бананы } фруктов.' );
Результатом будет: [9]
У меня есть 4 яблока. У меня есть 7 фруктов.
В Java 21 есть интерполированные строки благодаря JEP 430. В jshell вы можете напрямую использовать константу STR из java.lang.StringTemplate.
этап перечисления { тест , контроль качества , продукт } запись развертывания ( образ UUID , этап этапа ) {} var Deploy = new Deploy ( UUID.randomUUID ( ) , Stage.test ) _ _ СТР . "Установка \{deploy.image()} на сцене \{deploy.stage()} ..."var Deploy = новое развертывание ( UUID.randomUUID ( ) , Stage.prod ) _ _ СТР . "Установка \{deploy.image()} на сцене \{deploy.stage()} ..."
https://openjdk.org/jeps/430
JavaScript , начиная со стандарта ECMAScript 2015 (ES6), поддерживает интерполяцию строк с использованием обратных кавычек ``
. Эта функция называется литералами шаблонов . [10] Вот пример:
константные яблоки = 4 ; константные бананы = 3 ; консоль . log ( `У меня есть ${ apples } яблок` ); консоль . log ( `У меня есть ${ яблоки + бананы } фруктов` );
Результатом будет:
У меня есть 4 яблока, у меня 7 фруктов.
Литералы шаблонов также можно использовать для многострочных строк:
консоль . log ( `Это первая строка текста. Это вторая строка текста.` );
Результатом будет:
Это первая строка текста. Это вторая строка текста.
apples = 4 банана = 3 print ( «У меня есть $apples яблоки и $bananas бананы, в сумме получается $ ( apples + бананы ) кусочков фруктов». )
Результатом будет:
У меня есть 4 яблока и 3 банана, всего 7 фруктов.
val качество = "супергерой" val яблоки = 4 val бананы = 3 val предложение = "Разработчик - $ качество . У меня есть ${ яблоки + бананы } фруктов" println ( предложение )
Результатом будет:
Разработчик — супергерой. У меня есть 7 фруктов
защита яблок = 4 ; защита бананы = 3 ; Консоль . WriteLine ( $ "У меня есть яблоки $apples." ); Консоль . WriteLine ( $ "У меня есть $(яблоки + бананы) фрукты." );
Он также поддерживает расширенные функции форматирования, такие как:
def Fruit = [ "яблоко" , "банан" ]; Консоль . WriteLine ( $ < #У меня есть ..$(фрукты; "\n"; f => f + "s")#>);
Результатом будет:
яблоки бананы
Nim обеспечивает интерполяцию строк через модуль strutils. Форматированные строковые литералы, вдохновленные F-строкой Python, предоставляются через модуль strformat, макрос strformat проверяет, что строка формата правильно сформирована и типизирована, а затем расширяется в исходный код Nim во время компиляции.
import strutils , strformat var apples = 4 var Banans = 3 echo «У меня есть яблоки по 1 доллару » . формат ( яблоки ) echo fmt"У меня есть {яблоки} яблоки" echo fmt"У меня есть фрукты {яблоки + бананы}" # Многострочное echo fmt" "" У меня есть { apples } apples" "" # Отладка форматирования echo fmt"У меня есть {apples=} яблок" # Пользовательские символы openChar и closeChar echo fmt ( «У меня есть (apples) {apples}» , '(' , ')' ) # Обратная косая черта внутри форматированного строкового литерала echo fmt" "" { " да \ нет" } "" "
Результатом будет:
У меня есть 4 яблока У меня есть 4 яблока У меня 7 фруктов У меня 4 яблока У меня есть яблоки=4 яблока У меня 4 {яблока} да, опа
пусть NumberOfApples = "4" ; в «У меня ${ NumberOfApples } яблок»
Результатом будет:
у меня 4 яблока
const Apples := 4 const Bananas := 3 Println ( "У меня есть `(Apples) яблоки.\n" ) Println ( "У меня есть `(Apples+Bananas) фрукты.\n" )
Результатом будет:
У меня есть 4 яблока. У меня есть 7 фруктов.
мои $apples = 4 ; мои $бананы = 3 ; print "У меня есть $apples apples.\n" ; print "У меня есть фрукты @{[$apples+$bananas]}.\n" ; # Использует интерполяцию массива Perl (@).
Результатом будет:
У меня есть 4 яблока. У меня 7 фруктов.
<?php $apples = 5 ; $бананы = 3 ; echo "Есть $apples яблоки и $bananas бананы. \n " ; echo "У меня есть { $apples } яблок и { $bananas } бананов." ;
Результатом будет:
Есть 5 яблок и 3 банана. У меня есть 5 яблок и 3 банана.
Начиная с версии 3.6, Python поддерживает интерполяцию строк, называемую «форматированными строковыми литералами». [11] [12] [13] Такой литерал начинается с открывающей кавычки f
или перед ней и использует фигурные скобки для заполнителей:F
apples = 4 банана = 3 распечатайте ( f 'У меня есть { яблоки } яблоки и { бананы } бананы' )
Результатом будет:
У меня есть 4 яблока и 3 банана
apples = 4 puts "У меня #{ apples } apples" # Форматируем строку apps для сравнения: puts "У меня есть %s яблок" % apples puts "У меня есть %{a} яблок" % { a : apples }
Результатом будет:
у меня 4 яблока
Rust не имеет общей интерполяции строк, но предоставляет аналогичную функциональность через макросы, называемые «Захваченные идентификаторы в строках формата», представленные в версии 1.58.0, выпущенной 13 января 2022 г. [14]
Rust обеспечивает форматирование через модуль std::fmt, который взаимодействует с различными макросами, такими как format!, write! и print!. Эти макросы преобразуются в исходный код Rust во время компиляции, при этом каждый аргумент взаимодействует с форматером. Средство форматирования поддерживает позиционные параметры, именованные параметры, типы аргументов, определение различных характеристик форматирования и получение идентификаторов из среды.
пусть ( яблоки , бананы ) = ( 4 , 3 ); // печатьln! захватывает идентификаторы при форматировании: сама строка не интерполируется Rust. распечататьлн! ( "Есть {apples} яблоки и {bananas} бананы." );
Результатом будет:
Есть 4 яблока и 3 банана.
Scala 2.10+ предоставляет общие возможности для произвольной обработки строкового литерала и поддерживает интерполяцию строк с использованием встроенных s
и f
строковых интерполяторов. Также возможно написать собственные или переопределить стандартные.
Интерполятор f
— это макрос компилятора, который перезаписывает строку формата со встроенными выражениями при вызове String.format. Он проверяет, что строка формата правильно сформирована и типизирована.
Интерполяция строк в Scala 2.10+ позволяет встраивать ссылки на переменные непосредственно в обрабатываемые строковые литералы. Вот пример:
val apples = 4 val Banans = 3 //до Scala 2.10 printf ( «У меня есть %d яблок\n» , яблоки ) println ( «У меня есть %d яблок» формат яблок ) //Scala 2.10+ println ( s"У меня есть $ apples apples" ) println ( s"У меня есть ${ apples + бананы } фрукты" ) println ( f"У меня $ apples %d яблок" )
Результатом будет:
у меня 4 яблока
В Sciter любая функция, имя которой начинается с $, считается интерполирующей функцией, поэтому интерполяция настраивается и зависит от контекста:
вар яблок = 4 вар бананов = 3 вар domElement = ...; домЭлемент . $content ( < p > У меня есть { яблоки } яблок </p> ); домЭлемент . $append ( < p > У меня есть { яблоки + бананы } фрукты </p> );
Где
домЭлемент . $content ( < p > У меня есть { яблоки } яблок </p> );
компилируется так:
домЭлемент . html = "<p>У меня есть" + яблоки . toHtmlString () + "яблоки</p>" ;
яблоки = 4 ; бананы = 3 Выход = «У меня есть « яблоки » яблоки». Выход = "У меня есть " ( яблоки + бананы ) " фрукты."
Результатом будет:
У меня есть 4 яблока. У меня есть 7 фруктов.
В Swift новое значение String можно создать из сочетания констант, переменных, литералов и выражений, включив их значения в строковый литерал. [15] Каждый элемент, вставленный в строковый литерал, заключен в пару круглых скобок, перед которыми ставится обратная косая черта.
let apples = 4 print ( «У меня есть \ (apples) яблоки» )
Результатом будет:
у меня 4 яблока
Язык команд инструментов всегда поддерживал интерполяцию строк во всех строках, разделенных кавычками.
set apples 4 ставит «У меня есть $apples apples».
Результатом будет:
У меня есть 4 яблока.
Чтобы фактически отформатировать, а не просто заменить значения, существует функция форматирования.
set apples 4 puts [ format «У меня есть %d яблок». $яблоки ]
Начиная с версии 1.4, TypeScript поддерживает интерполяцию строк с помощью обратных кавычек ``
. Вот пример:
вар яблок : число = 4 ; консоль . log ( `У меня есть ${ apples } яблок` );
Результатом будет:
у меня 4 яблока
Функцию console.log
можно использовать как printf
функцию. Приведенный выше пример можно переписать следующим образом:
вар яблок : число = 4 ; консоль . log ( "У меня есть %d яблок" , apples );
Вывод остается прежним.
Начиная с Visual Basic 14, в Visual Basic поддерживается интерполяция строк. [16]
name = Консоль «Том» . WriteLine ( $ "Привет, {имя}" )
Результатом будет:
Привет, Том
Это намного аккуратнее, чем повторное использование символа «.». оператор конкатенации.