Cadenas de formato en GDScript

GDScript ofrece una funcionalidad llamada cadenas de formato que permite reutilizar plantillas de texto para crear distintas cadenas de una manera breve y compacta.

Las cadenas de formato son como las cadenas normales, excepto que contienen ciertas secuencias de caracteres asociadas entre sí. De esta forma, se pueden reemplazar fácilmente por parámetros entregados a la cadena de formato.

Por ejemplo, con %s como parámetro, la cadena de formato "Hello %s, how are you? puede cambiarse fácilmente por "Hello World, how are you?". Nota que el parámetro está en el medio de la cadena; modificarlo sin cadenas de formato podría ser engorroso.

Utilización en GDScript

Mira este ejemplo concreto en GDScript:

# Define a format string with placeholder '%s'
var format_string = "We're waiting for %s."

# Using the '%' operator, the placeholder is replaced with the desired value
var actual_string = format_string % "Godot"

print(actual_string)
# Output: "We're waiting for Godot."

Los parámetros siempre comienzan con %, pero el siguiente caracter o caracteres, el format specifier determina cómo el valor será convertido a cadena.

El %s visto en el ejemplo anterior es el más simple y se puede utilizar para la mayoría de los casos: convierte el valor con el mismo método por el cual una conversión implícita de String o str() lo haría. Las cadenas (string) se mantienen sin cambio, booleanos (bool) se convierten a "True" o "False", un entero o real (int, float) se convierte en decimal, otros tipos normalmente devuelven sus datos en una cadena formateada de una manera legible.

También hay otro modo de formatear texto en GDScript, el método String.format(). Este método reemplaza todas las ocurrencias de una clave en la cadena por el correspondiente valor. Puede utilizar arreglos o diccionarios para los pares clave/valor.

Arreglos (array) pueden ser utilizados como clave, índice, o mezclados (ver ejemplos). El orden sólo importa cuando es utilizado el índice o el estilo mixto .

Un ejemplo rápido en GDScript:

# Define a format string
var format_string = "We're waiting for {str}"

# Using the 'format' method, replace the 'str' placeholder
var actual_string = format_string.format({"str": "Godot"})

print(actual_string)
# Output: "We're waiting for Godot"

Existen otros «especificadores de formato» o format specifiers, pero son sólo aplicables cuando se utiliza el operador %.

Parámetros múltiples

Las cadenas de formato pueden contener múltiples variables. En cuyo caso, los valores son manejados en forma de array, un valor por variable (a menos que se utilice un especificador de formato con un *, ver Rellenador Dinamico):

var format_string = "%s was reluctant to learn %s, but now he enjoys it."
var actual_string = format_string % ["Estragon", "GDScript"]

print(actual_string)
# Output: "Estragon was reluctant to learn GDScript, but now he enjoys it."

Note que los valores son insertados en orden. Recuerde que todos los parámetros deben ser reemplazados de una vez, así que tiene que existir un número correcto de valores.

Especificadores de formato

Existen otros especificadores de formato aparte de s que pueden ser utilizado en parámetros. Estos consisten de uno o más caracteres. Algunos de ellos trabajan por sí mismos, como s, algunos se colocan antes que otros caracteres, otros sólo funcionan con ciertos valores o caracteres.

Tipos de parámetros

Uno y sólo uno de estos debe aparecer como último caracter en un especificador de formato. Aparde de s , estos requieren ciertos tipos de parámetros.

s Conversión simple a cadena (string) por el mismo método que una conversión implícita en cadena.
c Caracter Unicode simple. Espera un entero sin signo de 8 bits (unsigned 8-bit integer, 0-255) para un código de posición o una cadena de caracteres simple.
d Un número decimal. Espera un decimal o real (será redondeado).
o Un número octal. Espera un entero o real (será redondeado).
x Un número hexadecimal con letras en minúsculas. Espera un entero o real (será redondeado).
X Un número hexadecimal con letras en mayúsculas. Espera un número entero o real (será redondeado).
f Un número real. Espera un número entero o real.

Modificadores de parámetros

Estos caracteres aparecen antes de los mencionados anteriormente. Algunos de ellos sólo funcionan bajo ciertas condiciones.

+ En especificadores numéricos, muestra el signo + si es positivo.
Entero Define el relleno o padding. Rellenado con espacios o ceros si el entero comienza con 0 en un parámetro entero. Cuando se utiliza después de ., ver ..
. Antes de f, especifica la precisión a cero lugares decimales. Puede ser acompañada de números a cambiar. Rellenada con ceros.
- Rellena a la derecha, en lugar de la izquierda.
* Relleno dinámico, espera un parámetro entero adicional para especificar el relleno o precisión después ., de ver relleno dinámico.

Relleno

Los caracteres . (punto), * (asterisco), - (signo menos) y dígitos (0-9) son utilizados para relleno. Esto permite imprimir valores alineados verticalmente como en una columna, siempre que se utilice una fuente con ancho fijo.

Para rellenar una cadena a una longitud mínima, añade un número entero al specifier:

print("%10d" % 12345)
# output: "     12345"
# 5 leading spaces for a total length of 10

Si el entero comienza con 0, los valores enteros son rellenados con ceros en lugar de espacios en blanco:

print("%010d" % 12345)
# output: "0000012345"

La precisión puede ser especificada por números reales agregando un . (punto) con un entero posteriormente. Sin entero después de ., se utilizará una precisión de 0, redondeando al valor entero. El entero a usar para relleno debe aparecer antes que el el punto.

# Pad to minimum length of 10, round to 3 decimal places
print("%10.3f" % 10000.5555)
# Output: " 10000.556"
# 1 leading space

El caracter - provocará un relleno a la derecha en vez de la izquierda, útil para alineo de texto a la derecha:

print("%-10d" % 12345678)
# Output: "12345678  "
# 2 trailing spaces

Relleno dinámico

Al utilizar el caracter * (asterisco), el relleno o precisión podrán especificarse sin modificar la cadena string. Se usa en vez de un entero en el format specifier. Los valores para relleno y precisión son pasados al aplicarse el formato:

var format_string = "%*.*f"
# Pad to length of 7, round to 3 decimal places:
print(format_string % [7, 3, 8.8888])
# Output: "  8.889"
# 2 leading spaces

Es posible rellenar con ceros en las variables enteras agregando 0 antes del *:

print("%0*d" % [2, 3])
#output: "03"

Secuencias de escape

Para insertar un carácter literal % dentro de una cadena string, debe «escaparse» para para impedir que se lea como variable. Esto se consigue duplicando el carácter:

var health = 56
print("Remaining health: %d%%" % health)
# Output: "Remaining health: 56%"

Ejemplos de métodos de formateo

Los siguientes son algunos ejemplos de cómo utilizar las varias invocaciones del método String.format .

Tipo Estilo Ejemplo Resultado
Diccionario clave "Hola, {name} v{version}!".format({"name":"Godette", "version":"3.0"}) Hola, Godette v3.0!
Diccionario índice "Hola, {0} v{1}!".format({"0":"Godette", "1":"3.0"}) Hola, Godette v3.0!
Diccionario mezcla "Hola, {0} v{version}!".format({"0":"Godette", "version":"3.0"}) Hola, Godette v3.0!
Arreglo clave "Hola, {name} v{version}!".format([["version":"3.0"], ["name":"Godette"]) Hola, Godette v3.0!
Arreglo índice "Hola, {0} v{1}!".format(["Godette","3.0"]) Hola, Godette v3.0!
Arreglo mezcla "Hola, {name} v{0}!".format([3.0, ["name","Godette"]]) Hola, Godette v3.0!
Arreglo sin índice "Hola, {} v{}!".format(["Godette", "3.0"], "{}") Hola, Godette v3.0!

Los parámetros pueden ser personalizados cuando se utiliza String.format, aquí hay unos ejemplos sobre esa funcionalidad.

Tipo Ejemplo Resultado
Infijo (por defecto) "Hola, {0} v{1}".format(["Godette", "3.0"], "{_}") Hola, Godette v3.0
Sufijo "Hola, 0% v1%".format(["Godette", "3.0"], "_%") Hola, Godette v3.0
Prefijo "Hola, %0 v%1".format(["Godette", "3.0"], "%_") Hola, Godette v3.0

Combinar el método String.format y el operador % puede ser útil ya que String.format no tiene un modo de manipular la representación de números.

Ejemplo Resultado
"Hola, {0} v{version}".format({0:"Godette", "version":"%0.2f" % 3.114}) Hola, Godette v3.11