domingo, 24 de febrero de 2013

Pequena introducción as expresións regulares

As expresións regulares son unha forma de buscar patróns nun texto moi potente e común, atópanse por exemplo en ferramentas coma `sed`, `grep` e teñen soporte estándar en prácticamente calqueira linguaxe de scripting moderno.
Se ben orixinalmente as expresións regulares referíanse a unha notación para expresar alfabetos dos autómatas finitos co paso do tempo o uso do termo relaxouse e hoxe é comunmente usado para referirse as PCRE (expresións regulares compatibles con perl), máis potentes.

O propósito de este post é amosar os conceptos xerais destas ferramentas sen adentrarnos en ningunha linguaxe de programación en concreto, o final faráse referencia a distintos recursos para facer uso delas coas linguaxes e ferramentas antes referidas.

Nota: as imáxes foron xeradas a través do sitio regexper.com
Nota2: as expresións regulares estarán entre ‘/’ e ignonrarase o escapado coma nas cadeas raw de python (‘\n’ non será un salto de liña, senón un carácter ‘\’ seguido dunha ‘n’). 


Os tokens básicos

Con tokens referirémonos os distintos objectos dos que está composto un texto, no caso de que sexan caracteres sen significado especial (estes son ‘.\[]|()+*?{}’ ) pódese facer referencia a eles directamente:

/a/

/!/

/5/


Hai que facer especial mención o carácter ‘.’, que simboliza calquer carácter distinto do salto de liña e as combinacións representadas polo carácter ‘\’ e unha letra de ‘b’, d’, ‘s’ ou ‘w’:

/./  Calqueira carácter

/\\/ Un só \

/b/ Borde dunha verba

/d/ Díxito

/s/ Espacio en branco

/w/ Carácter dunha verba

No caso dos escribi-lo carácter que segue o ‘\’ en maiúsculas invertirase a combinación:

/B/ Non o bordo da verba

/D/ Non un díxito


/S/ Un carácter non en branco

/W/ Un carácter non pertencente a unha verba

No caso de que no canto destas letras o carácter que ven despois do ‘\’ sexa outra cousa interpretarase como se fora ese carácter, sen ningún significado especial.


Agrupando os tokens

Pero que pasa se queremos dar unha opción entre varios caracteres? Neste caso introducirémonos entre corchetes, por exemplo, poderíamos simular o ‘/\d/’ anterior así:
/[0123456789]/
 Pero no interior dos corchetes certos caracteres adquiren un significado especial, por exemplo o ‘-’ entre dous caracteres aceptará tódolos caracteres entre os dous (incluídos):
/[0-9]/
Máis comprensible, e se queremos caracteres que non sexan díxitos, pois se o primeiro carácter do conxunto é un ‘^’ fai a inversión:
/[^0-9]/
Tamén podemos dar distintos patróns a buscar, usando o ‘|’ para separálos:
/Hola, mundo|Hello world/


Se non queremos que este operados separe toda a expresión podémos definir grupos entre parénteses para limitar o seu alcance:
/C\+\+ é (potente|un monstro)/
Ademáis os grupos pódense usar para capturar unha parte da expresión (faranno a menos que poñamos ‘?:’ despois de abri-los parénteses, as ferramentas que tiran das expresións regulares permíten extraelos diréctamente, polo que son mói útiles buscando cousas no texto:
/Escollíches o número (\d)/


Patróns de repetición

É moi frecuente que busquemos que un certo grupo se de un número de veces non fixo, por exemplo, se queremos buscar un número decimal con un ou máis díxitos non nos serve só usar ‘/\d/’, neste caso o operador ‘+’ despois permite expresar que se busca unha ou máis veces:
/E agora vai un número: \d+/
Por suposto, tamén podemos buscar que non haxa ningunha vez (ou calquera número), con ‘*’:
/Cadéa entre < e >: <[^>]*>/
 Ou tamén unha ou nengunha, usando ‘?’:
/Número acabado en \.0\?: \d+(\.0)?/

Podemos tamén definir o número iteracións a mán, poñendoo entre chaves:
/Un número de 3 díxitos: \d{3}/
Ou un número variable de veces, separando o límite inferior e o superior cunha coma (ou poñéndoos en branco se non o queremos definir):
/Un número de 3 díxitos: \d{3,7}/

E hai máis, claro, pero con iso xa se pode facer de todo, se queredes buscar máis posibilidades, na wiki de python teñen unha boa listaxe.

[Referencias]
sed: Usando o flag `-r`
grep: Usando o flag `-P`
En Python
En Javascript
En perl

No hay comentarios:

Publicar un comentario