Lua
La coincidencia de patrones
Buscar..
Sintaxis
string.find (str, pattern [, init [, plain]]) - Devuelve el índice inicial y final de coincidencia en str
string.match (str, patrón [, índice]) - Hace coincidir un patrón una vez (comenzando en el índice)
string.gmatch (str, patrón): devuelve una función que recorre todas las coincidencias en str
string.gsub (str, pattern, repl [, n]) - Reemplaza subcadenas (hasta un máximo de n veces)
.
representa a todos los personajes%a
representa todas las letras%l
representa todas las letras minúsculas%u
representa todas las letras mayúsculas%d
representa todos los dígitos%x
representa todos los dígitos hexadecimales%s
representa todos los caracteres de espacio en blanco%p
representa todos los caracteres de puntuación%g
representa todos los caracteres imprimibles excepto el espacio%c
representa todos los caracteres de control[set]
representa la clase que es la unión de todos los caracteres en set.[^set]
representa el complemento de set*
coincidencia codiciosa 0 o más ocurrencias de la clase de personaje anterior+
coincidencia codiciosa 1 o más ocurrencias de la clase de personaje anterior-
coincidencia perezosa 0 o más apariciones de la clase de carácter anterior?
coincide exactamente con 0 o 1 ocurrencia de la clase de carácter anterior
Observaciones
A lo largo de algunos ejemplos, se usa la notación (<string literal>):function <string literal>
, que es equivalente a string.function(<string literal>, <string literal>)
porque todas las cadenas tienen un metatable con el conjunto de campos __index
a la tabla de string
.
Lua patrón a juego
En lugar de usar expresiones regulares, la biblioteca de cadenas Lua tiene un conjunto especial de caracteres que se usan en las coincidencias de sintaxis. Ambos pueden ser muy similares, pero la comparación de patrones de Lua es más limitada y tiene una sintaxis diferente. Por ejemplo, la secuencia de caracteres %a
coincide con cualquier letra, mientras que su versión en mayúsculas representa todos los caracteres que no son letras , todas las clases de caracteres (una secuencia de caracteres que, como un patrón, puede coincidir con un conjunto de elementos) se enumeran a continuación.
Clase de personaje | Sección correspondiente |
---|---|
%una | letras (AZ, az) |
%do | caracteres de control (\ n, \ t, \ r, ...) |
%re | dígitos (0-9) |
% l | letra minúscula (az) |
%pag | caracteres de puntuación (!,?, &, ...) |
% s | personajes espaciales |
% u | letras mayúsculas |
% w | Caracteres alfanuméricos (AZ, az, 0-9) |
%X | dígitos hexadecimales (\ 3, \ 4, ...) |
% z | el personaje con representación 0 |
. | Coincide con cualquier personaje |
Como se mencionó anteriormente, cualquier versión en mayúsculas de esas clases representa el complemento de la clase. Por ejemplo, %D
coincidirá con cualquier secuencia de caracteres sin dígitos:
string.match("f123", "%D") --> f
Además de las clases de caracteres, algunos personajes tienen funciones especiales como patrones:
( ) % . + - * [ ? ^ $
El carácter %
representa un carácter de escape, haciendo %?
coincide con una interrogación y %%
coincide con el símbolo de porcentaje. Puede usar el carácter %
con cualquier otro carácter no alfanumérico, por lo tanto, si necesita escapar, por ejemplo, una cita, debe usar \\
antes, que escapa cualquier carácter de una cadena lua.
Un conjunto de caracteres, representado entre corchetes ( []
), le permite crear una clase de carácter especial, combinando diferentes clases y caracteres individuales:
local foo = "bar123bar2341"
print(foo:match "[arb]") --> b
Puede obtener el complemento del conjunto de caracteres comenzando con ^
:
local foo = "bar123bar2341"
print(string.match(foo, "[^bar]")) --> 1
En este ejemplo, string.match
encontrará la primera aparición que no sea b , a o r .
Los patrones pueden ser más útiles con la ayuda de los modificadores de repetición / opcionales, los patrones en lua ofrecen estos cuatro caracteres:
Personaje | Modificador |
---|---|
+ | Una o mas repeticiones |
* | Cero o más repeticiones. |
- | También cero o más repeticiones. |
? | Opcional (cero o una ocurrencia) |
El carácter +
representa uno o más caracteres coincidentes en la secuencia y siempre devolverá la secuencia coincidente más larga:
local foo = "12345678bar123"
print(foo:match "%d+") --> 12345678
Como puede ver, *
es similar a +
, pero acepta cero apariciones de caracteres y se usa comúnmente para hacer coincidir espacios opcionales entre diferentes patrones.
El carácter -
también es similar a *
, pero en lugar de devolver la secuencia coincidente más larga, coincide con la más corta.
El modificador ?
coincide con un carácter opcional, lo que le permite hacer coincidir, por ejemplo, un dígito negativo:
local foo = "-20"
print(foo:match "[+-]?%d+")
El motor de coincidencia de patrones de Lua proporciona algunos elementos adicionales de coincidencia de patrones:
Elemento del personaje | Descripción |
---|---|
%n | para n entre 1 y 9 coincide con una subcadena igual a la cadena n-th capturada |
%bxy | hace coincidir la subcadena entre dos caracteres distintos (par equilibrado de x e y ) |
%f[set] | patrón de frontera: coincide con una cadena vacía en cualquier posición, de modo que el siguiente carácter pertenece al conjunto y el carácter anterior no pertenece al conjunto |
string.find (Introducción)
La funcion de find
Primero echemos un vistazo a la función string.find
en general:
La función string.find (s, substr [, init [, plain]])
devuelve el índice de inicio y fin de una subcadena si se encuentra, y nil de lo contrario, comenzando en el índice init
si se proporciona (el valor predeterminado es 1).
("Hello, I am a string"):find "am" --> returns 10 11
-- equivalent to string.find("Hello, I am a string", "am") -- see remarks
Introduciendo patrones
("hello world"):find ".- " -- will match characters until it finds a space
--> so it will return 1, 6
Todos excepto los siguientes caracteres se representan a sí mismos ^$()%.[]*+-?)
. Cualquiera de estos caracteres puede ser representado por un %
siguiendo al propio personaje.
("137'5 m47ch s0m3 d1g175"):find "m%d%d" -- will match an m followed by 2 digit
--> this will match m47 and return 7, 9
("stack overflow"):find "[abc]" -- will match an 'a', a 'b' or a 'c'
--> this will return 3 (the A in stAck)
("stack overflow"):find "[^stack ]"
-- will match all EXCEPT the letters s, t, a, c and k and the space character
--> this will match the o in overflow
("hello"):find "o%d?" --> matches o, returns 5, 5
("hello20"):find "o%d?" --> matches o2, returns 5, 6
-- the ? means the character is optional
("helllllo"):find "el+" --> will match elllll
("heo"):find "el+" --> won't match anything
("helllllo"):find "el*" --> will match elllll
("heo"):find "el*" --> will match e
("helelo"):find "h.+l" -- + will match as much as it gets
--> this matches "helel"
("helelo"):find "h.-l" -- - will match as few as it can
--> this wil only match "hel"
("hello"):match "o%d*"
--> like ?, this matches the "o", because %d is optional
("hello20"):match "o%d*"
--> unlike ?, it maches as many %d as it gets, "o20"
("hello"):match "o%d"
--> wouldn't find anything, because + looks for 1 or more characters
La función `gmatch`
Cómo funciona
La función string.gmatch
tomará una cadena de entrada y un patrón. Este patrón describe en qué recuperar realmente. Esta función devolverá una función que en realidad es un iterador. El resultado de este iterador coincidirá con el patrón.
type(("abc"):gmatch ".") --> returns "function"
for char in ("abc"):gmatch "." do
print char -- this prints:
--> a
--> b
--> c
end
for match in ("#afdde6"):gmatch "%x%x" do
print("#" .. match) -- prints:
--> #af
--> #dd
--> #e6
end
Introduciendo capturas:
Esto es muy similar a la función normal, sin embargo, solo devolverá las capturas en lugar de la coincidencia completa.
for key, value in ("foo = bar, bar=foo"):gmatch "(%w+)%s*=%s*(%w+)" do
print("key: " .. key .. ", value: " .. value)
--> key: foo, value: bar
--> key: bar, value: foo
end
La función gsub
no confunda con la función string.sub, que devuelve una subcadena!
Cómo funciona
argumento de cadena
("hello world"):gsub("o", "0")
--> returns "hell0 w0rld", 2
-- the 2 means that 2 substrings have been replaced (the 2 Os)
("hello world, how are you?"):gsub("[^%s]+", "word")
--> returns "word word, word word word?", 5
("hello world"):gsub("([^%s])([^%s]*)", "%2%1")
--> returns "elloh orldw", 2
argumento de la función
local word = "[^%s]+"
function func(str)
if str:sub(1,1):lower()=="h" then
return str
else
return "no_h"
end
end
("hello world"):gsub(word, func)
--> returns "hello no_h", 2
argumento de la mesa
local word = "[^%s]+"
sub = {}
sub["hello"] = "g'day"
sub["world"] = "m8"
("hello world"):gsub(word, sub)
--> returns "g'day m8"
("hello world, how are you?"):gsub(word, sub)
--> returns "g'day m8, how are you?"
-- words that are not in the table are simply ignored