Formatação de Strings em GDScript

GDScript offers a feature called format strings, which allows reusing text templates to succinctly create different but similar strings.

Strings de formatação são como strings normais, exceto que elas contém certas sequências de caracteres de substituição. Essas sequências podem ser facilmente substituídas por parâmetros passados para a string de formatação.

Como um exemplo, com %s como substituto, a string de formatação "Olá %s, como vai?" pode ser facilmente mudada para "Olá Mundo, como vai?". Note que o substituto está no meio da string; modificá-lo sem os formatos seria trabalhoso.

Uso na GDScript

Examine este exemplo concreto de 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."

Placeholders sempre começam com um %, mas o(s) próximo(s) caractere(s) o especificador de formato, determina como o valor dado é convertido em uma string.

O %s no exemplo acima é o mais simples dos espaços reservados e funciona para a maioria dos casos: Ele converte o valor pelo mesmo método pelo qual uma conversão implícita para String ou str() o faria. Strings não são alteradas, Booleanos são convertidos em "True" ou "False", um valor integral ou real se transfona em um decimal e outros tipos normalmente retornam o seu dado em uma string legível por humanos.

Existe também outra forma de formatar texto no GDScript, utilizando o método String.format(). Ele troca todas as ocorrências de uma chave na string pelo valor correspondente. O método consegue lidar com arrays ou dicionários para os pares de chave/valor.

Listas podem ser utilizadas como chave, index ou uma mistura de tipos (veja exemplos abaixo). A ordem importante apenas quando o Index ou a mistura de tipos da lista é utilizada.

Um exemplo rápido em 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"

Existem outros formatos especificadores, mas eles só são aplicáveis quando usado com o operador %.

Múltiplos espaços reservados

Strings de formatação podem conter múltiplos espaços reservados. Nesse caso, os valores são tratados na forma de um array, um valor para cada espaço reservado (a não ser que se use um especificador de formato com *, veja dynamic padding – “espaço de preenchimento dinâmico”):

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 os valores são inseridos em ordem. Lembre-se que todos os espaços reservados devem ser substituídos de uma vez, para isso o numero de valores deve ser apropriado.

Especificadores de formato

Existem outros especificadores de formato além de s que podem ser usados nos espaços reservados. Eles consistem de um ou mais caracteres. Alguns dos quais funcionam por conta própria como ser s, alguns aparecem antes de outros caracteres, e alguns apenas funcionam com certos tipos de valores ou caracteres.

Tipos de espaços reservados

Apenas um destes deve sempre aparecer como o ultimo caractere em um especificador de formato. Diferentemente do s, estes requerem certos tipos de parâmetros.

s Conversão simples para uma String pelo mesmo método que uma conversão implícita para String.
c Um único Caractere unicode. Espera um numero inteiro de 8-bits (0-255) representando o código do caractere ou uma string de um único caractere.
d Um número Inteiro decimal. Espera um numero inteiro ou real (que será aproximado para baixo).
o Um número inteiro octal. Espera um numero inteiro ou real (que será aproximado para baixo).
x Um número inteiro hexadecimal com letras em caixa-baixa. Espera um numero inteiro ou real (que será aproximado para baixo).
X Um número inteiro hexadecimal com letras em caixa-alta. Espera um numero inteiro ou real (que será aproximado para baixo).
f Um número decimal inteiro. Espera receber um número inteiro ou real.

Modificadores temporários

Estes caracteres aparecem antes dos acima. Alguns deles só funcionam em certas condições.

+ Nos especificadores numéricos, mostra o simbolo + se positivo.
Inteiro Define o espaçamento. Espaçado com espaços, ou com zeros caso o inteiro começe com 0 no espaço reservado. Quando usado após ., veja ..
. Antes de f, coloque a precisão para 0 casas decimais. Pode ser seguido com os números para mudar. Preenchido com zeros.
- Preencha para a direita ao invés da esquerda.
* Preenchimento dinâmico, espera parâmetro integral adicional para colocar o preenchimento ou precisão após ., veja preenchimento dinâmico.

Preenchimento

Os caracteres . (ponto), * (asterisco), - (sinal negativo) e dígitos (0-9) são usados para preenchimento. Isso permite mostrar vários valores alinhados verticalmente, como se fosse uma coluna, desde que uma fonte de largura fixa seja usada.

Para preencher um texto com comprimento mínimo, acrescente um inteiro ao especificador:

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

Se o inteiro inicia com 0, os valores inteiros serão preenchidos com zeros ao invés de com espaços em branco:

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

A precisão pode ser especificada para números reais adicionando um ``.``(ponto) com um número inteiro em seguida. Se nenhum número inteiro estiver após o ponto, uma precisão de 0 é utilizada, arredondando o número para um valor inteiro. O inteiro utilizado para espaçamento deve aparecer antes do ponto.

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

O caractere - fará um preenchimento para a direita, em vez de à esquerda, sendo útil para o alinhamento do texto à direita:

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

Preenchimento dinâmico

Ao usar o caractere * (asterisco), o preenchimento ou a precisão podem ser definidos sem modificar o texto de formatação. Isso é usado no lugar de um inteiro no especificador de formato. Os valores para preenchimento e precisão serão então passados ao formatar:

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

É possível preencher com zeros nos locais reservados para inteiros ao adicionar 0 antes de *:

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

Sequência de escape

Para inserir um caractere % literal em um texto de formatação, ele deve ser escapado para evitar que seja lido como um espaço reservado. Isso é feito duplicando o caractere:

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

Exemplos de métodos de formatação

Os seguintes são alguns exemplos de como usar as várias invocações do método String.format.

Tipo Estilo Exemplo Resultado
Dicionário chave "Hi, {name} v{version}!".format({"name":"Godette", "version":"3.0"}) Olá, Godette v3.0!
Dicionário índice "Hi, {0} v{1}!".format({"0":"Godette", "1":"3.0"}) Olá, Godette v3.0!
Dicionário mistura "Hi, {0} v{version}!".format({"0":"Godette", "version":"3.0"}) Olá, Godette v3.0!
Vetor chave "Hi, {name} v{version}!".format([["version","3.0"], ["name","Godette"]]) Olá, Godette v3.0!
Vetor índice "Hi, {0} v{1}!".format(["Godette","3.0"]) Olá, Godette v3.0!
Vetor mistura "Hi, {name} v{0}!".format([3.0, ["name","Godette"]]) Olá, Godette v3.0!
Vetor no index "Hi, {} v{}!".format(["Godette", 3.0], "{}") Olá, Godette v3.0!

Espaços reservados também podem ser personalizados utilizando String.format, aqui estão alguns exemplos dessa funcionalidade.

Tipo Exemplo Resultado
Infixo (padrão) "Hi, {0} v{1}".format(["Godette", "3.0"], "{_}") Oi, Godette v3.0
Pós-fixo "Hi, 0% v1%".format(["Godette", "3.0"], "_%") Oi, Godette v3.0
Prefixo "Hi, %0 v%1".format(["Godette", "3.0"], "%_") Oi, Godette v3.0

Combining both the String.format method and the % operator could be useful, as String.format does not have a way to manipulate the representation of numbers.

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