En programación informática , la interpolación de cadenas (o interpolación de variables , sustitución de variables o expansión de variables ) es el proceso de evaluar un literal de cadena que contiene uno o más marcadores de posición , arrojando un resultado en el que los marcadores de posición se reemplazan con sus valores correspondientes. Es una forma de procesamiento de plantillas simple [1] o, en términos formales, una forma de cuasi cita (o interpretación de sustitución lógica ). El marcador de posición puede ser un nombre de variable o, en algunos idiomas, una expresión arbitraria, en cualquier caso evaluada en el contexto actual .
La interpolación de cadenas es una alternativa a la creación de cadenas mediante concatenación , que requiere repetir las comillas y las comillas; [2] o sustituyendo en una cadena de formato printf , donde la variable está lejos de donde se usa. Comparar:
manzanas = 4 pone "Tengo #{ manzanas } manzanas". # la interpolación de cadenas pone "Tengo" + Cadena ( manzanas ) + "manzanas". # la concatenación de cadenas pone "Tengo %d manzanas". % manzanas # cadena de formato
Generalmente se ofrecen dos tipos de expresión literal: una con interpolación habilitada y la otra sin ella. Las cadenas no interpoladas también pueden escapar de secuencias , en cuyo caso se denominan cadena sin formato , aunque en otros casos esto está separado, lo que produce tres clases de cadena sin formato, cadena no interpolada (pero con escape) y cadena interpolada (y con escape). Por ejemplo, en shells de Unix, las cadenas entre comillas simples están sin formato, mientras que las cadenas entre comillas dobles están interpoladas. Los marcadores de posición suelen estar representados por un sigilo desnudo o con nombre (típicamente $
o %
), por ejemplo, $apples
o %apples
, o con llaves, por ejemplo {apples}
, a veces ambos, por ejemplo ${apples}
. En algunos casos se pueden utilizar especificadores de formato adicionales (como en printf), por ejemplo {apples:3}
, y en algunos casos los propios especificadores de formato se pueden interpolar, por ejemplo {apples:width}
. La expansión de la cadena generalmente ocurre en tiempo de ejecución .
El soporte de idiomas para la interpolación de cadenas varía ampliamente. Algunos lenguajes no ofrecen interpolación de cadenas, sino que utilizan concatenación, funciones de formato simples o bibliotecas de plantillas. La interpolación de cadenas es común en muchos lenguajes de programación que hacen un uso intensivo de representaciones de datos en cadenas , como Apache Groovy , Julia , Kotlin , Perl , PHP , Python , Ruby , Scala , Swift , Tcl y la mayoría de los shells de Unix .
Hay dos tipos principales de algoritmos de expansión de variables para la interpolación de variables : [3]
La interpolación de cadenas, al igual que la concatenación de cadenas, puede provocar problemas de seguridad. Si los datos de entrada del usuario se escapan o filtran incorrectamente, el sistema quedará expuesto a ataques de inyección SQL , inyección de script , inyección de entidad externa XML (XXE) y scripts entre sitios (XSS). [4]
Un ejemplo de inyección SQL:
consulta = " "SELECT x, y, z FROM Table WHERE id='$id'
Si $id
se reemplaza por " "';
, la ejecución de esta consulta borrará todos los datos del archivo DELETE FROM Table; SELECT * FROM Table WHERE id='
Table
.
DATOS ( manzanas ) = 4 . ESCRIBIR | Tengo { manzanas } manzanas |.
La salida será:
tengo 4 manzanas
manzanas = 4 echo "Tengo $manzanas manzanas" # o echo "Tengo ${ manzanas } manzanas"
La salida será:
tengo 4 manzanas
manzanas = 4 print ( "Tengo $(manzanas) manzanas" ) # o print ( "Tengo {0} manzanas" % manzanas )
La salida será:
tengo 4 manzanas
var manzanas = 4 ; var plátanos = 3 ; Consola . WriteLine ( $"Tengo {manzanas} manzanas" ); Consola . WriteLine ( $"Tengo {manzanas + plátanos} frutas" );
[5]
La salida será:
tengo 4 manzanas tengo 7 frutas
Sintaxis del script del lenguaje de marcado ColdFusion (CFML):
manzanas = 4 ; writeOutput ( "Tengo #manzanas# manzanas" );
Sintaxis de etiqueta:
<cfset manzanas = 4 > <cfoutput> Tengo # manzanas # manzanas </cfoutput>
La salida será:
tengo 4 manzanas
manzanas = 4 consolas . iniciar sesión "Tengo #{ manzanas } manzanas"
La salida será:
tengo 4 manzanas
int manzanas = 4 , plátanos = 3 ; print ( 'Tengo $ manzanas manzanas' ); print ( 'Tengo ${ manzanas + plátanos } frutas.' );
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
A partir de 2022 [actualizar], Go no tiene interpolación de cadenas. Ha habido algunas propuestas para la interpolación de cadenas en la próxima versión del lenguaje, Go 2. [6] [7] En cambio, Go usa cadenas en formato printf en la fmt.Sprintf
función, concatenación de cadenas o bibliotecas de plantillas como text/template
.
En Groovy, las cuerdas interpoladas se conocen como GStrings: [8]
def calidad = "superhéroe" edad final = 52 def frase = "Un desarrollador es una $calidad si tiene ${edad <= 42 ? 'joven' : 'experimentado'}" println frase
La salida será:
Un desarrollador es un superhéroe si tiene experiencia
var manzanas = 4 ; var plátanos = 3 ; trace ( 'Tengo $ manzanas manzanas' ); trace ( 'Tengo ${ manzanas + plátanos } frutas.' );
La salida será: [9]
Tengo 4 manzanas. Tengo 7 frutas.
Java 21 tiene cadenas interpoladas gracias a JEP 430. En jshell puedes usar la constante STR de java.lang.StringTemplate directamente.
enumeración Etapa { prueba , qa , prod } registrar implementación ( imagen UUID , etapa etapa ){} var implementar = nueva implementación ( UUID . randomUUID (), etapa . prueba ) FUERZA . "Instalando \{deploy.image()} en el escenario \{deploy.stage()} ..."var implementar = nueva implementación ( UUID . randomUUID (), etapa . prod ) FUERZA . "Instalando \{deploy.image()} en el escenario \{deploy.stage()} ..."
https://openjdk.org/jeps/430
JavaScript , a partir del estándar ECMAScript 2015 (ES6), admite la interpolación de cadenas mediante comillas invertidas ``
. Esta característica se llama literales de plantilla . [10] Aquí hay un ejemplo:
manzanas constantes = 4 ; plátanos constantes = 3 ; consola . log ( `Tengo ${ manzanas } manzanas` ); consola . log ( `Tengo ${ manzanas + plátanos } frutas` );
La salida será:
tengo 4 manzanas tengo 7 frutas
Los literales de plantilla también se pueden utilizar para cadenas de varias líneas:
consola . log ( `Esta es la primera línea de texto. Esta es la segunda línea de texto.` );
La salida será:
Esta es la primera línea de texto. Esta es la segunda línea de texto.
manzanas = 4 plátanos = 3 print ( "Tengo $manzanas, manzanas y $plátanos , plátanos, lo que hace $ ( manzanas + plátanos ) piezas de fruta en total." )
La salida será:
Tengo 4 manzanas y 3 plátanos, lo que hace 7 piezas de fruta en total.
val calidad = "superhéroe" val manzanas = 4 val plátanos = 3 val oración = "Un desarrollador es una $ calidad . Tengo ${ manzanas + plátanos } frutas" println ( oración )
La salida será:
Un desarrollador es un superhéroe. tengo 7 frutas
definitivamente manzanas = 4 ; plátanos definidos = 3 ; Consola . WriteLine ( $ "Tengo $manzanas manzanas." ); Consola . WriteLine ( $ "Tengo fruta $(manzanas + plátanos)." );
También admite funciones de formato avanzadas, como:
def fruta = [ "manzana" , "plátano" ]; Consola . WriteLine ( $ < #Tengo ..$(fruta; "\n"; f => f + "s")#>);
La salida será:
manzanas plátanos
Nim proporciona interpolación de cadenas a través del módulo strutils. Los literales de cadena formateados inspirados en la cadena F de Python se proporcionan a través del módulo strformat, la macro strformat verifica que la cadena de formato esté bien formada y escrita, y luego se expanden al código fuente de Nim en tiempo de compilación.
importar strutils , strformat var manzanas = 4 var plátanos = 3 echo "Tengo manzanas a $1 " . formato ( manzanas ) echo fmt"Tengo {manzanas} manzanas" echo fmt"Tengo {manzanas + plátanos} frutas" # Echo fmt de varias líneas " "" Tengo { manzanas } manzanas" "" # Depurar el formato echo fmt"Tengo {manzanas=} manzanas" # Los caracteres personalizados openChar y closeChar hacen eco de fmt ( "Tengo (manzanas) {manzanas}" , '(' , ')' ) # Barra invertida dentro del literal de cadena formateado echo fmt" "" { " sí \ no" } "" "
La salida será:
Tengo 4 manzanas Tengo 4 manzanas Tengo 7 frutas Tengo 4 manzanas Tengo manzanas = 4 manzanas Tengo 4 {manzanas} sí ope
let númeroDeManzanas = "4" ; en "Tengo ${ numberOfApples } manzanas"
La salida será:
tengo 4 manzanas
const Manzanas := 4 const Plátanos := 3 Println ( "Tengo `(Manzanas) manzanas.\n" ) Println ( "Tengo `(Manzanas+Plátanos) frutas.\n" )
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
mis $manzanas = 4 ; mis $plátanos = 3 ; print "Tengo $manzanas manzanas.\n" ; print "Tengo @{[$manzanas+$bananas]} fruta.\n" ; # Utiliza la interpolación de matriz Perl (@).
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
<?php $manzanas = 5 ; $plátanos = 3 ; echo "Hay $manzanas manzanas y $plátanos plátanos. \n " ; echo "Tengo { $manzanas } manzanas y { $bananas } plátanos." ;
La salida será:
Hay 5 manzanas y 3 plátanos. Tengo 5 manzanas y 3 plátanos.
Python admite la interpolación de cadenas a partir de la versión 3.6, denominada "literales de cadena formateados". [11] [12] [13] Dicho literal comienza con f
o F
antes de la comilla inicial y utiliza llaves como marcadores de posición:
manzanas = 4 plátanos = 3 print ( f 'Tengo { manzanas } manzanas y { plátanos } plátanos' )
La salida será:
tengo 4 manzanas y 3 plátanos
manzanas = 4 pone "Tengo #{ manzanas } manzanas" # Aplicaciones de cadena de formato para comparación: pone "Tengo %s manzanas" % manzanas pone "Tengo %{a} manzanas" % { a : manzanas }
La salida será:
tengo 4 manzanas
Rust no tiene interpolación de cadenas general, pero proporciona una funcionalidad similar a través de macros, denominadas "Identificadores capturados en cadenas de formato", introducidas en la versión 1.58.0, lanzada el 13 de enero de 2022. [14]
Rust proporciona formato a través del módulo std::fmt, con el que se interconecta a través de varias macros como format!, write! e print!. Estas macros se convierten al código fuente de Rust en tiempo de compilación, donde cada argumento interactúa con un formateador. El formateador admite parámetros posicionales, parámetros con nombre, tipos de argumentos, define varios rasgos de formato y captura identificadores del entorno.
let ( manzanas , plátanos ) = ( 4 , 3 ); // imprimir! captura los identificadores al formatear: Rust no interpola la cadena en sí. imprimir! ( "Hay {manzanas} manzanas y {plátanos} plátanos." );
La salida será:
Hay 4 manzanas y 3 plátanos.
Scala 2.10+ proporciona una función general para permitir el procesamiento arbitrario de un literal de cadena y admite la interpolación de cadenas utilizando los interpoladores s
de f
cadena incluidos. También es posible escribir personalizados o anular los estándar.
El f
interpolador es una macro compiladora que reescribe una cadena de formato con expresiones incrustadas como una invocación de String.format. Verifica que la cadena de formato esté bien formada y escrita.
La interpolación de cadenas de Scala 2.10+ permite incrustar referencias de variables directamente en cadenas literales procesadas. Aquí hay un ejemplo:
val manzanas = 4 val plátanos = 3 //antes de Scala 2.10 printf ( "Tengo %d manzanas\n" , manzanas ) println ( "Tengo %d manzanas" formato manzanas ) //Scala 2.10+ println ( s"Tengo $ manzanas manzanas" ) println ( s"Tengo ${ manzanas + plátanos } frutas" ) println ( f"Tengo $ manzanas %d manzanas" )
La salida será:
tengo 4 manzanas
En Sciter, cualquier función con un nombre que comience desde $ se considera una función de interpolación, por lo que la interpolación es personalizable y sensible al contexto:
var manzanas = 4 var plátanos = 3 var domElement = ...; elementodom . $content ( < p > tengo { manzanas } manzanas < /p > ); elementodom . $append ( < p > tengo { manzanas + plátanos } frutas < / p>);
Dónde
elementodom . $content ( < p > tengo { manzanas } manzanas < /p > );
se compila a esto:
elementodom . html = "<p>Tengo " + manzanas . toHtmlString () + "manzanas</p>" ;
manzanas = 4 ; plátanos = 3 Salida = "Tengo " manzanas " manzanas." Salida = "Tengo " ( manzanas + plátanos ) "frutas".
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
En Swift , se puede crear un nuevo valor de cadena a partir de una combinación de constantes, variables, literales y expresiones incluyendo sus valores dentro de una cadena literal. [15] Cada elemento insertado en la cadena literal está entre paréntesis, precedido por una barra invertida.
let manzanas = 4 print ( "Tengo \ (manzanas) manzanas" )
La salida será:
tengo 4 manzanas
El lenguaje de comandos de herramientas siempre ha admitido la interpolación de cadenas en todas las cadenas delimitadas por comillas.
set apples 4 pone "Tengo $apples manzanas".
La salida será:
Tengo 4 manzanas.
Para formatear realmente, y no simplemente reemplazar, los valores, existe una función de formato.
set apples 4 puts [ formato "Tengo %d manzanas." $manzanas ]
A partir de la versión 1.4, TypeScript admite la interpolación de cadenas mediante comillas invertidas ``
. Aquí hay un ejemplo:
var manzanas : número = 4 ; consola . log ( `Tengo ${ manzanas } manzanas` );
La salida será:
tengo 4 manzanas
La console.log
función se puede utilizar como una printf
función. El ejemplo anterior se puede reescribir de la siguiente manera:
var manzanas : número = 4 ; consola . log ( "Tengo %d manzanas" , manzanas );
La salida sigue siendo la misma.
A partir de Visual Basic 14, la interpolación de cadenas es compatible con Visual Basic. [16]
nombre = Consola "Tom" . WriteLine ( $ "Hola, {nombre}" )
La salida será:
Hola tom
Esto es mucho más ordenado que los usos repetidos del '.' operador de concatenación.