Строковая интерполяция
В компьютерном программировании интерполяция строк (или интерполяция переменных , замена переменных или расширение переменных ) — это процесс оценки строкового литерала , содержащего один или несколько заполнителей , дающий результат, в котором заполнители заменяются соответствующими значениями. Это форма простой обработки шаблонов. [1] или, формально говоря, форма квазицитаты (или логической подстановки интерпретации ). Заполнителем может быть имя переменной или, в некоторых языках, произвольное выражение, в любом случае оцениваемое в текущем контексте .
Интерполяция строк — это альтернатива построению строки посредством конкатенации , которая требует повторного заключения и удаления кавычек; [2] или подстановка в строку формата printf , где переменная находится далеко от того места, где она используется. Сравнивать:
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
Обычно предлагаются два типа буквального выражения: один с включенной интерполяцией, другой без. Неинтерполированные строки также могут экранировать последовательности , и в этом случае они называются необработанной строкой , хотя в других случаях это отдельно, что дает три класса необработанной строки, неинтерполированной (но экранированной) строки, интерполированной (и экранированной) строки. Например, в оболочках 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-инъекции:
query = "SELECT x, y, z FROM Table WHERE id='$id'
"
Если $id
заменяется на " ';
" , выполнение этого запроса уничтожит все данные в DELETE FROM Table; SELECT * FROM Table WHERE id='
Table
.
Примеры
[ редактировать ]АБАП
[ редактировать ]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
[ редактировать ]Синтаксис сценария языка разметки ColdFusion (CFML):
apples = 4;
writeOutput("I have #apples# apples");
Синтаксис тега:
<cfset apples = 4>
<cfoutput>I have #apples# apples</cfoutput>
Результатом будет:
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} fruits.');
Результатом будет:
I have 4 apples.
I have 7 fruits.
Идти
[ редактировать ]По состоянию на 2022 год [update], В Go нет интерполяции строк. Было несколько предложений по интерполяции строк в следующей версии языка Go 2. [6] [7] Вместо этого Go использует строки формата printf в fmt.Sprintf
функции, конкатенация строк или библиотеки шаблонов, такие как text/template
.
классный
[ редактировать ]В groovy интерполированные строки называются GStrings: [8]
def quality = "superhero"
final age = 52
def sentence = "A developer is a $quality if he is ${age <= 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} fruits.');
Результатом будет: [9]
I have 4 apples.
I have 7 fruits.
Ява
[ редактировать ]В Java 21 есть интерполированные строки благодаря JEP 430. В jshell вы можете напрямую использовать константу STR из java.lang.StringTemplate .
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()} ..."
JavaScript
[ редактировать ]JavaScript , согласно стандарту ECMAScript 2015 (ES6), поддерживает интерполяцию строк с использованием обратных кавычек. ``
. Эта функция называется литералами шаблонов . [10] Вот пример:
const apples = 4;
const bananas = 3;
console.log(`I have ${apples} apples`);
console.log(`I have ${apples + bananas} fruits`);
Результатом будет:
I have 4 apples
I have 7 fruits
Литералы шаблонов также можно использовать для многострочных строк:
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} fruits"
println(sentence)
Результатом будет:
A developer is a superhero. I have 7 fruits
Немерль
[ редактировать ]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($<#I have ..$(fruit; "\n"; f => f + "s")#>);
Результатом будет:
apples
bananas
Nim
[ редактировать ]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) fruits.\n")
Результатом будет:
I have 4 apples.
I have 7 fruits.
Перл
[ редактировать ]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.
PHP
[ редактировать ]<?php
$apples = 5;
$bananas = 3;
echo "There are $apples apples and $bananas bananas.\n";
echo "I have {$apples} apples and {$bananas} bananas.";
Результатом будет:
There are 5 apples and 3 bananas.
I have 5 apples and 3 bananas.
Питон
[ редактировать ]Python поддерживает интерполяцию строк начиная с версии 3.6, называемую
«форматированные строковые литералы». [11] [12] [13] Такой литерал начинается с f
или F
перед открывающей кавычкой и использует фигурные скобки для заполнителей:
apples = 4
bananas = 3
print(f'I have {apples} apples and {bananas} bananas')
Результатом будет:
I have 4 apples and 3 bananas
Рубин/Кристалл
[ редактировать ]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}
Результатом будет:
I have 4 apples
Ржавчина
[ редактировать ]В Rust нет общей интерполяции строк, но он предоставляет аналогичную функциональность через макросы, называемые «Захваченные идентификаторы в строках формата», представленные в версии 1.58.0, выпущенной 13 января 2022 г. [14]
Rust обеспечивает форматирование через модуль std::fmt , который взаимодействует с различными макросами, такими как format! , писать! и распечатайте! . Эти макросы преобразуются в исходный код 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.");
Результатом будет:
There are 4 apples and 3 bananas.
Скала
[ редактировать ]Scala 2.10+ предоставляет общие возможности для произвольной обработки строкового литерала и поддерживает интерполяцию строк с использованием включенного s
и f
строковые интерполяторы. Также возможно написать собственные или переопределить стандартные.
The 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(<p>I have {apples} apples</p>);
domElement.$append(<p>I have {apples + bananas} fruits</p>);
Где
domElement.$content(<p>I have {apples} apples</p>);
компилируется так:
domElement.html = "<p>I have " + apples.toHtmlString() + " apples</p>";
Сноболь
[ редактировать ] apples = 4 ; bananas = 3
Output = "I have " apples " apples."
Output = "I have " (apples + bananas) " fruits."
Результатом будет:
I have 4 apples.
I have 7 fruits.
Быстрый
[ редактировать ]В Swift новое значение String можно создать из сочетания констант, переменных, литералов и выражений, включив их значения в строковый литерал. [15] Каждый элемент, вставленный в строковый литерал, заключен в пару круглых скобок, перед которыми ставится обратная косая черта.
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
The console.log
функцию можно использовать как printf
функция. Приведенный выше пример можно переписать следующим образом:
var apples: number = 4;
console.log("I have %d apples", apples);
Вывод остается прежним.
Визуальный Бейсик
[ редактировать ]Начиная с Visual Basic 14, в Visual Basic поддерживается интерполяция строк. [16]
name = "Tom"
Console.WriteLine($"Hello, {name}")
Результатом будет:
Hello, Tom
См. также
[ редактировать ]Примечания
[ редактировать ]- ^ « Обеспечение строгого разделения модели и представления в механизмах шаблонов », Т. Парр (2004), конференция WWW2004.
- ^ «Интерполяция в Perl» .
Это намного аккуратнее, чем повторное использование символа «.». оператор конкатенации.
- ^ «Самая маленькая система шаблонов / Простейшие алгоритмы» , онлайн-руководство по системам шаблонов-заполнителей.
- ^ «Безопасная интерполяция строк» . google-caja.googlecode.com . Архивировано из оригинала 19 октября 2012 г.
- ^ «Строки — Руководство по программированию на C#» . 15 марта 2024 г.
- ^ «Предложение: Шаг 2: интерполяция строк № 34174» . Гитхаб .
- ^ «Предложение: Шаг 2: интерполяция строки, вычисляющая строку и список выражений #50554» . Гитхаб .
- ^ «Язык программирования Apache Groovy — Синтаксис» . groovy-lang.org . Проверено 20 июня 2021 г.
- ^ "Haxe - Руководство - Интерполяция строк" . Haxe — Кроссплатформенный набор инструментов . Проверено 12 сентября 2017 г.
- ^ «Литералы шаблона (строки шаблона) — JavaScript | MDN» . 31 мая 2024 г.
- ^ «Учебник по Python: 7.1.1. Форматированные строковые литералы» .
- ^ «Справочник по языку Python: 2.4.3. Форматированные строковые литералы» .
- ^ «PEP 498 — Интерполяция буквальных строк» .
- ^ «Анонсируем Rust 1.58.0: фиксируемые идентификаторы в строках формата» . 13 января 2022 г.
- ^ «Строки и символы — язык программирования Swift (Swift 5.5)» . docs.swift.org . Проверено 20 июня 2021 г.
- ^ Кэтлин Доллард. «Интерполированные строки — Visual Basic» . docs.microsoft.com . Проверено 20 июня 2021 г.