El tipo de dato cadena es una secuencia de caracteres, como letras, números y símbolos. Es el tipo de dato para almacenar la mayoría de la información basada en texto.
Declarar cadenas
Para declarar una variable de cadena, coloca comillas alrededor de los caracteres. Es más común usar comillas dobles ("), pero las comillas simples (') también funcionan. Si deseas incluir una comilla simple o doble en tu cadena, encierra tu cadena en el otro tipo de comillas, o utiliza una comilla escapada.
local string1 = "¡Hola mundo!"print(string1) --> ¡Hola mundo!local string2 = '¡Hola "mundo"!'print(string2) --> ¡Hola "mundo"!
Para incluir tanto comillas simples como dobles en una cadena, o para crear cadenas multilínea, decláralas utilizando corchetes dobles:
local string1 = [[Holamundo!¡Hola "mundo"!¡Hola 'mundo'!]]print(string1)--> Hola--> mundo!--> ¡Hola "mundo"!--> ¡Hola 'mundo'!
Si es necesario, puedes anidar múltiples corchetes dentro de una cadena utilizando el mismo número de signos de igual en ambos, el corchete de inicio y el de cierre:
local string1 = [=[Hola[[mundo!]]]=]print(string1)--> Hola--> [[mundo!]]
Combinar cadenas
Para combinar cadenas, concaténalas con dos puntos (..). La concatenación de cadenas no inserta un espacio entre ellas, por lo que deberás incluir espacio(s) al final/principio de una cadena anterior/siguiente, o concatenar un espacio entre las dos cadenas.
local hello = "Hola"local helloWithSpace = "Hola "local world = "mundo!"local string1 = hello .. worldlocal string2 = helloWithSpace .. worldlocal string3 = hello .. " " .. worldprint(string1) --> Holamundo!print(string2) --> Hola mundo!print(string3) --> Hola mundo!
Nota que el comando print() toma múltiples argumentos y los combina con espacios, por lo que puedes usar , en lugar de .. para obtener espacios en las salidas de print().
local hello = "Hola"local world = "mundo"local exclamationMark = "!"print(hello .. world .. exclamationMark) --> Holamundo!print(hello, world .. exclamationMark) --> Hola mundo!print(hello, world, exclamationMark) --> Hola mundo !
Convertir cadenas
Para convertir una cadena a un número, usa la función tonumber(). Si la cadena no tiene una representación numérica, tonumber() devuelve nil.
local numericString = "123"print(tonumber(numericString)) --> 123local alphanumericString = "Hola123"print(tonumber(alphanumericString)) --> nil
Escapar cadenas
Para escapar una declaración de cadena con comillas dobles o simples e incrustar casi cualquier carácter, coloca un signo de barra invertida (\) antes del carácter. Por ejemplo:
- Para incrustar una comilla simple en una cadena con comillas simples, usa \'.
- Para incrustar una comilla doble en una cadena con comillas dobles, usa \".
local string1 = '¡Hola \'mundo\'!'print(string1) --> ¡Hola 'mundo'!local string2 = "¡Hola \"mundo\"!"print(string2) --> ¡Hola "mundo"!
Ciertos caracteres que siguen a las barras invertidas producen caracteres especiales en lugar de caracteres escapados:
- Para incrustar una nueva línea, usa \n.
- Para incrustar una tabulación horizontal, usa \t.
local string1 = "¡Hola\nmundo!"print(string1)--> ¡Hola--> mundo!local string2 = "¡Hola\tmundo!"print(string2) --> ¡Hola mundo!
Interpolación de cadenas
Luau admite la interpolación de cadenas, una característica que te permite insertar expresiones en cadenas. Usa comillas invertidas (`) para declarar una cadena interpolada, luego añade expresiones dentro de llaves:
local world = "mundo"local string1 = `¡Hola {world}!`print(string1) --> ¡Hola mundo!
Aunque las variables son el uso más común, puedes usar cualquier expresión, incluida la matemática:
local world = "mundo"local number = 1local letters = {"m", "u", "n", "d", "o"}local string1 = `¡Hola {world}, {number} vez!`local string2 = `¡Hola {world}, {number + 1} veces!`local string3 = `¡Hola {table.concat(letters)} una tercera vez!`print(string1) --> ¡Hola mundo, 1 vez!print(string2) --> ¡Hola mundo, 2 veces!print(string3) --> ¡Hola mundo una tercera vez!
Las reglas de escape estándar aplican para las comillas invertidas, llaves y barras invertidas:
local string1 = `¡Hola \`\{world\}\`!`print(string1) --> ¡Hola `{world}`!
Conversión matemática
Si realizas operaciones matemáticas en una cadena, Luau convierte automáticamente la cadena en un número. Si la cadena no tiene una representación numérica, genera un error.
print("55" + 10) --> 65print("55" - 10) --> 45print("55" * 10) --> 550print("55" / 10) --> 5.5print("55" % 10) --> 5print("Hola" + 10) --> print("Hola" + 10):1: intento de realizar aritmética (suma) en cadena y número
Comparaciones
Las cadenas pueden ser comparadas utilizando los operadores <, <=, > y >=, que comparan usando el orden lexicográfico basado en los códigos ASCII de cada carácter en una cadena. Esto resultará en que los números en cadenas no se comparen correctamente, por ejemplo, "100" será menor que "20", ya que los bytes "0" y "1" tienen códigos ASCII más bajos que el byte "2".
print("Manzana" < "manzana") --> trueprint("Banana" < "manzana") --> true (B está antes que a en ASCII)print("numero100" < "numero20") --> true
Referencia de patrones de cadena
Un patrón de cadena es una combinación de caracteres que puedes usar con string.match(), string.gmatch() y otros funciones para encontrar un trozo, o subcadena, de una cadena más larga.
Coincidencias directas
Puedes usar coincidencias directas en una función de Luau como string.match(), excepto por los caracteres mágicos. Por ejemplo, estos comandos buscan la palabra Roblox dentro de una cadena:
local match1 = string.match("¡Bienvenido a Roblox!", "Roblox")local match2 = string.match("¡Bienvenido a mi increíble juego!", "Roblox")print(match1) --> Robloxprint(match2) --> nil
Clases de caracteres
Las clases de caracteres son esenciales para búsquedas de cadenas más avanzadas. Puedes usarlas para buscar algo que no necesariamente es específico de un carácter, sino que encaja dentro de una categoría (clase) conocida, que incluye letras, dígitos, espacios, signos de puntuación y más.
La siguiente tabla muestra las clases de caracteres oficiales para patrones de cadena en Luau:
| Clase | Representa | Ejemplo de coincidencia |
|---|---|---|
| . | Cualquier carácter | 32kasGJ1%fTlk?@94 |
| %a | Una letra mayúscula o minúscula | aBcDeFgHiJkLmNoPqRsTuVwXyZ |
| %l | Una letra minúscula | abcdefghijklmnopqrstuvwxyz |
| %u | Una letra mayúscula | ABCDEFGHIJKLMNOPQRSTUVWXYZ |
| %d | Cualquier dígito (número) | 0123456789 |
| %p | Cualquier carácter de puntuación | !@#;,. |
| %w | Un carácter alfanumérico (ya sea una letra o un número) | aBcDeFgHiJkLmNoPqRsTuVwXyZ0123456789 |
| %s | Un espacio o carácter de espacio en blanco | , \n, y \r |
| %c | Un carácter de control especial | |
| %x | Un carácter hexadecimal | 0123456789ABCDEF |
| %z | El carácter NULL (\0) |
Para las clases de caracteres de una sola letra como %a y %s, la letra correspondiente en mayúscula representa la "oposición" de la clase. Por ejemplo, %p representa un carácter de puntuación mientras que %P representa todos los caracteres excepto los de puntuación.
Caracteres mágicos
Hay 12 "caracteres mágicos" que están reservados para propósitos especiales en patrones:
| $ | % | ^ | * | ( | ) |
| . | [ | ] | + | - | ? |
Puedes escapar y buscar caracteres mágicos usando el símbolo %. Por ejemplo, para buscar roblox.com, escapa el símbolo . (punto) precediéndolo con un %, como en %..
-- "roblox.com" coincide con "roblox#com" porque el punto es interpretado como "cualquier carácter"local match1 = string.match("¿Qué es roblox#com?", "roblox.com")print(match1) --> roblox#com-- Escapa el punto con % para que sea interpretado como un carácter literal de puntolocal match2 = string.match("¡Amo roblox.com!", "roblox%.com")print(match2) --> roblox.com
Anclas
Puedes buscar un patrón al principio o al final de una cadena utilizando los símbolos ^ y $.
local start1 = string.match("primero segundo tercero", "^primero") -- Coincide porque "primero" está al principioprint(start1) --> primerolocal start2 = string.match("tercero segundo primero", "^primero") -- No coincide porque "primero" no está al principioprint(start2) --> nillocal end1 = string.match("primero segundo tercero", "tercero$") -- Coincide porque "tercero" está al finalprint(end1) --> tercerolocal end2 = string.match("tercero segundo primero", "tercero$") -- No coincide porque "tercero" no está al finalprint(end2) --> nil
También puedes usar ambos ^ y $ juntos para asegurarte de que un patrón coincide solo con la cadena completa y no solo con una parte de ella.
-- Usando tanto ^ como $ para coincidir en una cadena completalocal match1 = string.match("Roblox", "^Roblox$") -- Coincide porque "Roblox" es toda la cadena (igualdad)print(match1) --> Robloxlocal match2 = string.match("Yo juego Roblox", "^Roblox$") -- No coincide porque "Roblox" no está al principio Y al finalprint(match2) --> nillocal match3 = string.match("Yo juego Roblox", "Roblox") -- Coincide porque "Roblox" está contenida dentro de "Yo juego Roblox"print(match3) --> Roblox
Modificadores de clase
Por sí solo, una clase de caracteres solo coincide con un carácter en una cadena. Por ejemplo, el siguiente patrón ("%d") comienza a leer la cadena de izquierda a derecha, encuentra el primer dígito (2) y se detiene.
local match = string.match("El Reino de las Nubes tiene 25 gemas de poder", "%d")print(match) --> 2
Puedes usar modificadores con cualquier clase de caracteres para controlar el resultado:
| Cuantificador | Significado |
|---|---|
| + | Coincidir 1 o más del carácter de clase anterior |
| - | Coincidir con la menor cantidad posible del carácter de clase anterior |
| * | Coincidir 0 o más del carácter de clase anterior |
| ? | Coincidir 1 o menos del carácter de clase anterior |
| %n | Para n entre 1 y 9, coincide con una subcadena igual a la nésima cadena capturada. |
| %bxy | La coincidencia de captura equilibrada que coincide con x, y y todo entre (por ejemplo, %b() coincide con un par de paréntesis y todo lo que hay entre ellos) |
Añadir un modificador al mismo patrón ("%d+" en lugar de "%d"), produce 25 en lugar de 2:
local match1 = string.match("El Reino de las Nubes tiene 25 gemas de poder", "%d")print(match1) --> 2local match2 = string.match("El Reino de las Nubes tiene 25 gemas de poder", "%d+")print(match2) --> 25
Conjuntos de clases
Se deben usar conjuntos cuando una sola clase de caracteres no puede hacer todo el trabajo. Por ejemplo, podrías querer coincidir tanto letras minúsculas (%l) como caracteres de puntuación (%p) utilizando un solo patrón.
Los conjuntos se definen con corchetes [] alrededor de ellos. En el siguiente ejemplo, nota la diferencia entre usar un conjunto ("[%l%p]+") y no usar un conjunto ("%l%p+").
local match1 = string.match("¡Hola!!! Soy otra cadena.", "[%l%p]+") -- Conjuntoprint(match1) --> ello!!!local match2 = string.match("¡Hola!!! Soy otra cadena.", "%l%p+") -- No conjuntoprint(match2) --> o!!!
El primer comando (conjunto) le dice a Luau que encuentre tanto caracteres en minúscula como puntuación. Con el cuantificador + añadido después de todo el conjunto, encuentra todos esos caracteres (ello!!!), deteniéndose cuando llega al espacio.
En el segundo comando (no conjunto), el cuantificador + solo se aplica a la clase %p que está antes de él, por lo que Luau captura solo el primer carácter en minúscula (o) antes de la serie de puntuación (!!!).
Al igual que las clases de caracteres, los conjuntos pueden ser "opuestos" a sí mismos. Esto se hace al añadir un carácter ^ al principio del conjunto, justo después del corchete de apertura [. Por ejemplo, "[%p%s]+" representa tanto puntuación como espacios, mientras que "[^%p%s]+" representa todos los caracteres excepto puntuación y espacios.
Los conjuntos también admiten rangos que te permiten encontrar un rango entero de coincidencias entre un carácter inicial y uno final. Esta es una característica avanzada que se detalla más en el Manual de Lua 5.1.
Capturas de cadena
Las capturas de cadena son subpatrones dentro de un patrón. Estos están encerrados en paréntesis () y se utilizan para obtener (capturar) subcadenas coincidentes y guardarlas en variables. Por ejemplo, el siguiente patrón contiene dos capturas, (%a+) y (%d+), que devuelven dos subcadenas al hacer una coincidencia exitosa.
local pattern = "(%a+)%s?=%s?(%d+)"local key1, val1 = string.match("Veintiuno = 21", pattern)print(key1, val1) --> Veintiuno 21local key2, val2 = string.match("DosMil= 2000", pattern)print(key2, val2) --> DosMil 2000local key3, val3 = string.match("UnMillón=1000000", pattern)print(key3, val3) --> UnMillón 1000000
El cuantificador ? que sigue a ambas clases %s es una adición segura porque hace que el espacio a cada lado del signo = sea opcional. Eso significa que la coincidencia tiene éxito si uno (o ambos) espacios faltan alrededor del signo igual.
En la función string.gsub(), puedes incluir grupos de captura en la cadena de reemplazo usando %1, %2, %3, etc., hasta %9. A pesar de que Luau admite hasta 32 grupos de captura antes de generar un error, solo puedes hacer referencia a los primeros nueve con esta sintaxis:
local str = "amor2jugar Roblox"local pattern = "(%w+)(%d+)(%w+)%s+(%w+)"local replacement = "¡Yo %1 %2 %3 %4!"local result = string.gsub(str, pattern, replacement)print(result) --> ¡Yo amo 2 jugar Roblox!
También puedes anidar capturas de cadenas:
local places = "El Reino de las Nubes es celestial, El Reino del Bosque es pacífico"local pattern = "(El%s(%a+%sReino)[%w%s]+)"for description, kingdom in string.gmatch(places, pattern) doprint(description)print(kingdom)end--> El Reino de las Nubes es celestial--> Reino de las Nubes--> El Reino del Bosque es pacífico--> Reino del Bosque
Esta búsqueda de patrones funciona de la siguiente manera:
El iterador string.gmatch() busca una coincidencia en el patrón de toda la "descripción" definido por el par exterior de paréntesis. Esto se detiene en la primera coma y captura lo siguiente:
| # | Patrón | Captura |
|---|---|---|
| 1 | (El%s(%a+%sReino)[%w%s]+) | El Reino de las Nubes es celestial |
Usando su primera captura exitosa, el iterador luego busca una coincidencia en el patrón "reino" definido por el par interior de paréntesis. Este patrón anidado simplemente captura lo siguiente:
| # | Patrón | Captura |
|---|---|---|
| 2 | (%a+%sReino) | Reino de las Nubes |
Luego, el iterador retrocede y continúa buscando en la cadena completa, capturando lo siguiente:
| # | Patrón | Captura |
|---|---|---|
| 3 | (El%s(%a+%sReino)[%w%s]+) | El Reino del Bosque es pacífico |
| 4 | (%a+%sReino) | Reino del Bosque |
Además de todo lo anterior, hay un caso especial con una captura vacía (()). Si una captura está vacía, entonces la posición en la cadena se capturará:
local match1 = "¿Dónde ocurre la captura? ¡Quién sabe!"local match2 = "Esta cadena es más larga que la primera. ¿Dónde ocurre la captura? ¡Quién sabe?!"local pattern = "()¿Dónde ocurre la captura%? ¡Quién sabe!()"local start1, finish1 = string.match(match1, pattern)print(start1, finish1) --> 1 42local start2, finish2 = string.match(match2, pattern)print(start2, finish2) --> 43 84
Estas capturas especiales pueden anidarse como las normales:
local places = "El Reino de las Nubes es celestial, El Reino del Bosque es pacífico."local pattern = "El (%a+()) Reino es %a+"for kingdom, position in string.gmatch(places, pattern) doprint(kingdom, position)end--> Nubes 10--> Bosque 42
Los valores devueltos son inusuales en que son números en lugar de cadenas:
local match = "Este es un ejemplo"local pattern = "Este es un ()ejemplo"local position = string.match(match, pattern)print(typeof(position)) --> number