stringtranslate.com

Строковая интерполяция

В компьютерном программировании строковая интерполяция (или интерполяция переменных , замена переменных или расширение переменных ) — это процесс оценки строкового литерала , содержащего один или несколько заполнителей , дающий результат, в котором заполнители заменяются соответствующими значениями. Это форма простой обработки шаблонов [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]

  1. Замена и расширение заполнителей : создание новой строки из исходной с помощью операций поиска и замены. Найдите ссылку на переменную (заполнитель), замените ее значением переменной. Этот алгоритм не предлагает никакой стратегии кэширования.
  2. Разделение и объединение строки : разделение строки на массив, ее слияние с соответствующим массивом значений, а затем объединение элементов путем конкатенации. Разделенную строку можно кэшировать для повторного использования.

Проблемы с безопасностью

Интерполяция строк, как и конкатенация строк, может привести к проблемам безопасности. Если вводимые пользователем данные неправильно экранируются или фильтруются, система будет подвержена атакам 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

Синтаксис сценария языка разметки 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

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

<?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

Начиная с Visual Basic 14, в Visual Basic поддерживается интерполяция строк. [16]

name = Консоль «Том» . WriteLine ( $ "Привет, {имя}" )  

Результатом будет:

Привет, Том

Смотрите также

Примечания

  1. ^ «Обеспечение строгого разделения модели и представления в механизмах шаблонов», Т. Парр (2004), конференция WWW2004.
  2. ^ «Интерполяция в Perl». Это намного аккуратнее, чем повторное использование символа «.». оператор конкатенации.
  3. ^ «Самая маленькая система шаблонов / Простейшие алгоритмы», онлайн-руководство по системам шаблонов-заполнителей.
  4. ^ «Безопасная интерполяция строк». google-caja.googlecode.com . Архивировано из оригинала 19 октября 2012 г.
  5. ^ «Строки — Руководство по программированию на C#» .
  6. ^ «Предложение: Шаг 2: интерполяция строк № 34174» . Гитхаб .
  7. ^ «Предложение: Шаг 2: интерполяция строки, вычисляющая строку и список выражений № 50554» . Гитхаб .
  8. ^ «Язык программирования Apache Groovy — Синтаксис» . groovy-lang.org . Проверено 20 июня 2021 г.
  9. ^ "Haxe - Руководство - Интерполяция строк" . Haxe — кроссплатформенный набор инструментов . Проверено 12 сентября 2017 г.
  10. ^ «Литералы шаблонов (строки шаблонов) — JavaScript | MDN» .
  11. ^ «Учебник по Python: 7.1.1. Форматированные строковые литералы» .
  12. ^ «Справочник по языку Python: 2.4.3. Форматированные строковые литералы».
  13. ^ «PEP 498 — Интерполяция буквальных строк» ​​.
  14. ^ «Анонс Rust 1.58.0: фиксируемые идентификаторы в строках формата» . 13 января 2022 г.
  15. ^ «Строки и символы — язык программирования Swift (Swift 5.5)» . docs.swift.org . Проверено 20 июня 2021 г.
  16. ^ Кэтлин Доллард. «Интерполированные строки — Visual Basic». docs.microsoft.com . Проверено 20 июня 2021 г.