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 una cadena literal que contiene uno o más marcadores de posición , lo que produce 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 lenguajes, una expresión arbitraria, en cualquier caso evaluada en el contexto actual .
La interpolación de cadenas es una alternativa a la construcción de cadenas mediante concatenación , que requiere repetir el uso de comillas y descomillas [2] o sustituir en una cadena con formato printf , donde la variable está lejos de donde se utiliza. Comparar:
manzanas = 4 puts "Tengo #{ manzanas } manzanas." # interpolación de cadenas puts "Tengo " + String ( manzanas ) + " manzanas." # concatenación de cadenas puts "Tengo %d manzanas." % manzanas # formato de cadena
Se ofrecen normalmente dos tipos de expresiones literales: una con interpolación habilitada, la otra sin ella. Las cadenas no interpoladas también pueden escapar secuencias , en cuyo caso se denominan cadena sin formato , aunque en otros casos esto es independiente, lo que produce tres clases de cadena sin formato, cadena no interpolada (pero escapada) y cadena interpolada (y escapada). Por ejemplo, en los shells de Unix, las cadenas entre comillas simples son sin formato, mientras que las cadenas entre comillas dobles se interpolan. Los marcadores de posición suelen estar representados por un sigilo simple o con nombre (normalmente $
or %
), p. ej . $apples
or %apples
, o con llaves, eg {apples}
, a veces ambos, eg ${apples}
. En algunos casos se pueden utilizar especificadores de formato adicionales (como en printf), eg {apples:3}
, y en algunos casos se pueden interpolar los propios especificadores de formato, eg {apples:width}
. La expansión de la cadena suele producirse en tiempo de ejecución .
La compatibilidad de los lenguajes con 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 cadenas de datos, 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 ingresados por el usuario se escapan o filtran de manera incorrecta, el sistema estará expuesto a ataques de inyección SQL , inyección de script , inyección de entidad externa XML (XXE) y ataques de secuencias de comandos entre sitios (XSS). [4]
Un ejemplo de inyección SQL:
consulta = " "SELECT x, y, z FROM Table WHERE id='$id'
Si $id
se reemplaza con " "';
, al ejecutar esta consulta se borrarán todos los datos en 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 ; Console . WriteLine ( $"Tengo {manzanas} manzanas" ); Console . WriteLine ( $"Tengo {manzanas + plátanos} frutas" );
[5]
La salida será:
Tengo 4 manzanas Tengo 7 frutas
Sintaxis del script de ColdFusion Markup Language (CFML):
manzanas = 4 ; writeOutput ( "Tengo #manzanas# manzanas" );
Sintaxis de la etiqueta:
<cfset apples = 4 > <cfoutput> Tengo # manzanas # manzanas </cfoutput>
La salida será:
Tengo 4 manzanas
manzanas = 4 console.log "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 su lugar, Go usa cadenas de formato printf en la función, concatenaciónfmt.Sprintf
de cadenas o bibliotecas de plantillas como .text/template
En Groovy, las cadenas interpoladas se conocen como GStrings: [8]
def calidad = "superhéroe" edad final = 52 def oración = "Un desarrollador es de $calidad si es ${edad <= 42 ? 'joven' : 'experimentado'}" println oración
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 tenía cadenas interpoladas como una característica de vista previa en Java 21 y Java 22. Podía usar la constante STR de java.lang.StringTemplate directamente.
enumeración Etapa { prueba , qa , prod } registro Implementar ( UUID imagen , Etapa etapa ){} var implementar = nueva implementación ( UUID . randomUUID (), etapa . prueba ) STR . "Instalando \{deploy.image()} en Stage \{deploy.stage()} ..."var implementar = new Implementar ( UUID . randomUUID (), Etapa . prod ) STR . "Instalando \{deploy.image()} en Stage \{deploy.stage()} ..."
Se eliminaron en Java 23 debido a problemas de diseño. [10]
JavaScript , a partir del estándar ECMAScript 2015 (ES6), admite la interpolación de cadenas mediante comillas simples invertidas ``
. Esta característica se denomina literales de plantilla . [11] A continuación, se muestra un ejemplo:
const manzanas = 4 ; const plátanos = 3 ; console . log ( `Tengo ${ manzanas } manzanas` ); console . 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:
console.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 $bananas 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 un total de 7 piezas de fruta.
val calidad = "superheroe" val manzanas = 4 val bananas = 3 val frase = "Un desarrollador es una $ calidad . Tengo ${ manzanas + bananas } frutas" println ( frase )
La salida será:
Un desarrollador es un superhéroe. Tengo 7 frutas.
def manzanas = 4 ; def plátanos = 3 ; Console . WriteLine ( $ "Tengo $manzanas manzanas." ); Console . WriteLine ( $ "Tengo $(manzanas + plátanos) frutas." );
También admite funciones de formato avanzadas, como:
def fruta = [ "manzana" , "banana" ]; Console . 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 Python F-string se proporcionan a través del módulo strformat, la macro strformat verifica que la cadena de formato esté bien formada y tipificada, y luego se expanden al código fuente de Nim en tiempo de compilación.
import strutils , strformat var manzanas = 4 var bananas = 3 echo "Tengo $1 manzanas" . format ( manzanas ) echo fmt "Tengo {manzanas} manzanas" echo fmt "Tengo {manzanas + bananas} frutas" # Eco multilínea fmt" "" Tengo { manzanas } manzanas " "" # Depurar el formato echo fmt"Tengo {manzanas=} manzanas" # Caracteres openChar y closeChar personalizados echo fmt ( "Tengo (manzanas) {manzanas}" , '(' , ')' ) # Barra invertida dentro del literal de cadena formateada echo fmt" "" { " yep \ nope" } "" "
La salida será:
Tengo 4 manzanas Tengo 4 manzanas Tengo 7 frutas Tengo 4 manzanas Tengo manzanas=4 manzanas Tengo 4 {manzanas} sí abierto
deje que numberOfApples = "4" ; en "tengo ${ numberOfApples } manzanas"
La salida será:
Tengo 4 manzanas
const Manzanas := 4 const Bananas := 3 Println ( "Tengo `(Manzanas) manzanas.\n" ) Println ( "Tengo `(Manzanas+Bananas) frutas.\n" )
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
mis $manzanas = 4 ; mis $bananas = 3 ; print "Tengo $manzanas manzanas.\n" ; print "Tengo @{[$manzanas+$bananas]} frutas.\n" ; # Utiliza la interpolación de matriz (@) de Perl.
La salida será:
Tengo 4 manzanas. Tengo 7 frutas.
<?php $manzanas = 5 ; $bananas = 3 ; echo "Hay $manzanas manzanas y $bananas 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". [12] [13] [14] Un literal de este tipo comienza con un f
o F
antes de la comilla de apertura 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 puts "Tengo #{ manzanas } manzanas" # Formato de cadena aplicaciones para comparación: puts "Tengo %s manzanas" % manzanas puts "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, publicada el 13 de enero de 2022. [15]
Rust proporciona formato a través del módulo std::fmt, con el que se interactúa a través de varias macros como format!, write! y print!. Estas macros se convierten en código fuente de Rust en tiempo de compilación, por lo que cada argumento interactúa con un formateador. El formateador admite parámetros posicionales, parámetros nombrados, tipos de argumentos, define varias características de formato y captura identificadores del entorno.
let ( manzanas , plátanos ) = ( 4 , 3 ); // println! captura los identificadores al formatear: la cadena en sí no es interpolada por Rust. println! ( "Hay {manzanas} manzanas y {plátanos} plátanos." );
La salida será:
Hay 4 manzanas y 3 plátanos.
Scala 2.10+ ofrece una función general que permite el procesamiento arbitrario de un literal de cadena y admite la interpolación de cadenas mediante los interpoladores de cadena incluidos s
y f
de cadena. También es posible escribir interpoladores personalizados o anular los estándares.
El f
interpolador es una macro del compilador que reescribe una cadena de formato con expresiones integradas como una invocación de String.format. Verifica que la cadena de formato esté bien formada y tipificada.
La interpolación de cadenas de Scala 2.10+ permite incorporar referencias de variables directamente en literales de cadena procesados. A continuación, se muestra un ejemplo:
val manzanas = 4 val bananas = 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 + bananas } frutas" ) println ( f"Tengo $ manzanas %d manzanas" )
La salida será:
Tengo 4 manzanas
En Sciter, cualquier función cuyo nombre comience con $ se considera una función de interpolación y, por lo tanto, la interpolación es personalizable y sensible al contexto:
var manzanas = 4 var plátanos = 3 var domElement = ...; domElement . $ content ( <p> tengo { manzanas } manzanas </p> ) ; domElement . $ append ( <p> tengo { manzanas + plátanos } frutas </p> ) ;
Dónde
domElement . $content ( < p > tengo { manzanas } manzanas </p> ) ;
Se compila de esta manera:
domElement . 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 un literal de cadena. [16] Cada elemento insertado en el literal de cadena está envuelto en un par de paréntesis, precedido por una barra invertida.
deje que 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 $manzanas manzanas".
La salida será:
Tengo 4 manzanas.
Para poder 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 simples invertidas ``
. A continuación, se muestra un ejemplo:
var manzanas : numero = 4 ; console . 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 : numero = 4 ; console . 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. [17]
nombre = " Tom" Console.WriteLine ( $ "Hola, { nombre}" )
La salida será:
Hola, Tom
Esto es mucho más ordenado que los usos repetidos del operador de concatenación '.'.