Bienvenidos sean a este post, el mecanismo de captura permite a un patron tirar partes de la cadena dada que coincide con las partes de un patron para uso posterior.

Anuncios

Esto permite especificar una captura escribiendo las partes del patron que quieras capturar entre parentesis, cuando un patron tiene capturas la funcion string.match devuelve cada valor capturado como un resultado a parte, es decir que separa a la cadena en distintas partes:

par = "nombre = martin"
clave, valor = string.match(par, "(%a+)%s*=%s*(%a+)")
print(clave, valor)                  -- Devuelve nombre  martin
Anuncios

El patron ‘%a+’ especifica una secuencia no vacia de letras, el patron ‘%s*’ especifica una posible secuencia vacia de caracteres, asi que en el ejemplo superior el patron completo especifica una secuencia de letras seguido por una secuencia de espacios, seguido por un ‘=’ y de nuevo seguido por espacios y finalmente una secuencia de letras, ambas secuencias de letras tienen sus patrones encerrados por parentesis, y estos seran capturados si una coincidencia ocurre, abajo tenemos un ejemplo similar:

> dia = "Hoy es 01/11/2019"
> d, m, a = string.match(dia, "(%d+)/(%d+)/(%d+)")
> print(d, m, a)
01      11      2019
>
Nota: Hasta la version Lua 5.0 string.find hacia esta tarea.
Anuncios

Podemos usar capturas en el patron mismo, en un patron un item como ‘%d’ es solo un digito, coincide con solo una copia de la captura de d, como un tipico uso suponemos que queres encontrar dentro de una cadena una subcadena encerrado entre comillas simples y dobles, podes intentar un patron tipo ‘[“‘].-[“‘]’ que es una comilla seguida por cualquier cosa a su vez seguido por otra comilla pero aun tendrias problemas con cadenas como “it’s all right”, para resolver este problema podes capturar la primer comilla y usarlo para especificar la segunda comilla, veamos el codigo:

> s = [[ Luego el dijo, "it's all right" ]]
> c, parteComillada = string.match(s, "([\"'])(.-)%1")
> print(parteComillada)
it's all right
> print(c)
"
>
Anuncios

La primer captura es el caracter de comilla mismo y la segunda captura es el contenido de la comilla (la subcadena que coincide con ‘.-‘), un ejemplo similar es el patron que coincide a lo largo de la cadena en Lua:

%[(=*)%[(.-)%]%1%)
Anuncios

Coincidira con un corchete de apertura seguido por cero o mas signos iguales, seguido por otro corchete de apertura, luego seguido por cualquier cosa (el contenido de la cadena), despues seguido por un corchete de cierre, seguido por el mismo numero de signos iguales, luego seguido por otro corchete de cierre:

> p = "%[(=*)%[(.-)%]%1%]"
> s = "a = [=[[[ algo ]] ]==] ]=]; print(a)"
> print(string.match(s,p))
=       [[ algo ]] ]==]
>
Anuncios

La primera captura es la secuencia de signos iguales (solo uno en este ejemplo), el segundo es el contenido de la cadena, el tercer uso de los valores capturados es en la cadena de reemplazo en gsub, como el patron tambien la cadena de reemplazo podria contener items como ‘%d’ los cuales son cambiados a la captura respectiva cuando la sustitucion esta hecha, en particular el item ‘%o’ es cambiado a la coincidencia entera (por cierto un ‘%’ en la cadena de reemplazo debe ser escapado como ‘%%’), en el siguiente ejemplo el comando duplica cada letra en una cadena con un guion entre las copias:

> print(string.gsub("Hola Lua!","%a","%0-%0"))
H-Ho-ol-la-a L-Lu-ua-a! 7
>
Anuncios

Este intercambia los caracteres adyacentes:

> print(string.gsub("Hola Lua!", "(.)(.)", "%2%1"))
oHalL au!       4
>
Anuncios

Un ejemplo mas util puede ser un convertidor de formato primitivo, la cual consigue una cadena con comando escritos en un estilo LaTeX tal como:

\command{algun texto}

y los cambias a un formato de estilo XML:

<command>algun texto</command>
Anuncios

Si no permitimos comandos anidados la siguiente linea hace el trabajo:

s = string.gsub(s, "\\(%a+){(.-)}", "<%1>%2</%1>")
Anuncios

Apliquemos el caso anterior de la siguiente forma:

> s = "la \\quote{tarea} es para \\em{cambiar} esto"
> print(string.gsub(s, "\\(%a+){(.-)}", "<%1>%2</%1>"))
la <quote>tarea</quote> es para <em>cambiar</em> esto   2
>
Anuncios

En el primer caso aplicamos una doble barra para que el interprete la tome como una sola, luego al llamar a gsub vemos como primero busca la barra (en este caso de vuelta doble para que sepa que es ese caracter), luego la secuencia sin faltante de letras para despues seguir con el contenido entre las dos llaves, el reemplazo tomara el contenido despues de la barra y lo usara en 1, el contenido de las llaves lo usara en 2, por eso al momento de convertirlo lo asigna correctamente.

Nota: Mas adelante veremos esto mismo pero con comandos anidados.
Anuncios

Otro ejemplo practico es como quitar todos los espacios en blanco de una cadena, esta accion en general es llamada trim:

function trim(s)
	return (string.gsub(s, "^%s+(.-)%s*$", "%1"))
end

Tengan en cuenta que el uso de juicios para formato de patrones, como el uso de las dos anclas (‘^’ y ‘$’), nos aseguran que consigamos toda la cadena porque el patron ‘.-‘ se trata de expandir lo menos posible, los dos patrones ‘%s*’ coinciden con todos los espacios en ambas extremidades, debido a que gsub devuelve dos valores, la sustitucion y el contador, debemos usar doble parentesis para omitir este dato.

Anuncios

En resumen, hoy hemos visto que son las capturas, como son, para que usan, como se utilizan, su funcion principal y otros usos que podemos aplicar, espero les haya sido util sigueme en Twitter o Facebook para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tengo un Patreon donde podes acceder de manera exclusiva a material para este blog antes de ser publicado, sigue los pasos del link para saber como.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00