Viquipèdia:Viquitrobada 2009/Taller de bots/Expressions regulars

Una expressió regular permet definir un conjunt de cadenes. Una cadena pertany al conjunt definit per una expressió regular si coincideix en l'expressió regular.

Les expressions regulars consisteixen en cadenes de caràcters que han de trobar-se en un text. Per a substituir o declarar certs caràcters i conjunts de caràcters semblants s'empren els "metacaràcters". Una expressió regular es declara, com les cadenes de caràcters, dins de cometes simples o dobles.

Els “metacaràcters” són: . ^ $ * + ? { } [ ] \ | ( )

Tots els altres són caràcters normals. Un metacaràcter es transforma en caràcter normal si s'escriu precedit d'un caràcter d'escapada ("\"), així "\$" s'interpreta com el caràcter normal "$". Per transformar en caràcter normal el "\", cal escriure'n dos de seguits, així "\\" s'interpreta com el caràcter normal "\".

Si una expressió regular està formada només per caràcters normals, la única cadena que hi encaixa és la pròpia cadena en què consisteix l'expressió regular, així l'expressió regular "Hola" defineix un conjunt de cadenes amb un únic element que és la cadena "Hola", o l'expressió regular "Preu = 500\$" defineix un conjunt de cadenes amb un únic element que és la cadena "Preu = 500$".

L'avantatge de les expressions regulars és que a més de poder definir cadenes permet dues característiques més: que un caràcter de la cadena pertanyi a un conjunt i que un caràcter o tota una expressió regular es pugui repetir. Amb aquestes dues característiques addicionals les expressions regulars es converteixen en una eina molt potent a l'hora de definir conjunts de cadenes per a cercar en un text.

Conjunts de caràcters

modifica

Si en una expressió regular hi ha el metacaracter “.” hi encaixen totes les cadenes que encaixin en la resta de l'expressió regular independentment del caràcter que tinguin el la posició on hi ha el punt (excepte el caràcter “salt de línia”). Per exemple l'expressió regular (“.”) defineix el conjunt de totes les cadenes de un únic caràcter, l'expressió regular (“.ala”) defineix el conjunt de totes les cadenes de 4 caràcters que tinguin els caràcters “ala” en les posicions segona, tercera i quarta independentment de quin sigui el caràcter que tinguin en la posició primera, així les cadenes “ ala”, “bala”, “pala”, “%ala”... pertanyen totes al conjunt definit per l'expressió regular. El metacaràcter “.” representa al conjunt de tots els caràcters tret del salt de línia”

Els metacaracters “[“ i “]” es fan servir per definir conjunts de caràcters. Si en una expressió regular apareix un conjunt de caràcters en una posició determinada, en aquella posició hi encaixa qualsevol caràcter que pertanyi a aquell conjunt. Una manera de fer servir aquests metacaràcters per definir un conjunt és ficar-los encerclant una cadena, per exemple [abc] defineix el conjunt format pels caràcters “a”, “b” i “c” . Per exemple l'expressió regular (“[b p]ala”) defineix el conjunt de cadenes de 4 caràcters tals que el seu primer caràcter és un membre del conjunt definit per [b p] i els caràcters segon tercer i quart són respectivament “a”, “l”, i “a” per tant, defineix el conjunt de cadenes els elements del qual són: “bala”, “ ala” i “pala” i no forma part d'aquest conjunt la cadena “%ala”.

Els metacaràcters “^”,”-“ i “\” tenen un significat especial dins de la definició d'un conjunt de caràcters.

El metacaràcter “–“ serveix per definir conjunts de caràcters que estan seguits en el codi ASCII sense haver-los d'escriure un per un, només escrivint el primer i l'últim, així el conjunt definit per [abcdef] és el mateix que el definit per [a-f] (compte que les vocals accentuades i lletres com la “ç” no estan per ordre alfabètic en el codi ASCII.

El matacaràcter “^” si es coloca al començament de la cadena serveix per definir el complementari d'un conjunt (en qualsevol altre lloc simplement s'interpreta com el caràcter “^”). Per exemple, el conjunt [^ ] és el conjunt de tots el caràcters tret de l'espai en blanc.

El matacaràcter \ davant de certes lletres serveix per designar certs conjunts de caràcters predefinits: \d dígits decimals: \D tot tret dels dígits decimals. \s qualsevol caràcter de tipus espai blanc és a dir: espai en blanc, tabulador, salt de línia, retorn de carro, \f i \v. \S Tot tret dels caràcters tipus espai blanc. \w qualsevol caràcter alfanumèric i \W tot tret dels caràcters alfanumèrics.

Tot això es pot combinar, per exemple, l'expressió regular: (“a[\s.]b[a-z\d]c”) defineix el conjunt de cadenes de 5 caràcters tals que els seus caràcters primer tercer i cinquè són respectivament “a”, “b” i “c” i els seus caràcters segon i quart pertanyen respectivament als conjunts definits per [\s.] i [a-v\d], on el conjunt definit per [\.] és o bé un caràcter de tipus espai blanc (incloent per tant el salt de línia) o bé qualsevol caràcter tret del salt de línia (que és el que indica el “.”) per tant és qualsevol caràcter incloent-hi el salt de línia i on el conjunt definit per [a-v\d] és qualsevol lletra minúscual de la “a” a la “v” ambdues incloses o un dígit decimal. Per tant les cadenes “a%b3c” i “abbvd” pertanyen al conjunt mentre que les cadenes “abbxd” i “b%b3c” no.

Repeticions

modifica

Els metacaràcters “+”, “*”, “?” i “{“, “}” es fan servir per indicar repeticions de l'objecte precedent que pot ser un caràcter o una expressió regular. + indica 1 vegada o més, * cap o més, ? cap o una i {n,m} entre n i m repeticions totes dues incloses.

Per exemple les expressions regulars:

“ab?c” defineix el conjunt de cadenes amb els elments: “abc” i “ac”, la primera cadena “encaixa” perquè el caracter “b” es repeteix una vegada i la segona e”encaixa” perquè no es repeteix cap vegada.

“ab{2,5}c” defineix el conjunt de cadenes que té els elements: “abbc”, “abbbc”, “abbbbc” i “abbbbc” que encaixen perquè en totes elles el caràcter “b” es repeteix entre 2 i 5 vegades, però no conté la cadena “abc” ni la cadena “abbbbbbc” perque en el primer cas el caracter “b” només es repeteix una vegada i en el segon es repeteix 6 vegades.

“ab*c” defineix el conjunt de cadenes amb infinits elements (en la pràctica el màxim són 2 bilions de repeticions) que conté els elements: “ac”, “abc”, “abbc”, “abbbc”... Cal tenir en compte que 0 repeticions, és a dir la absència del caràcter, encaixa.

“ab+c” defineix el conjunt de cadenes amb infinits elements (en la pràctica el màxim són 2 bilions de repeticions) que conté els elements: “abc”, “abbc”, “abbbc”... Ara no s'admet 0 repeticions, és a dir la absència del caràcter, no encaixa.

A l'esquerra dels metacaràcters de repetició també hi pot haver un conjunt. Per exemple l'expressió regular “a[1-3]?b” defineix el conjunt de cadenes amb els elements: “ab”, “a1b”, “a2b” i “a3b” el primer perquè té 0 repeticions i els tres següents perquè hi ha una repetició d'elements que pertanyen al conjunt definit per [1-3]. Per exemple l'expressió regular “a[12]{1,2}b” defineix el conjunt format per les cadenes: “a1b”, “a2b”, “a11b”, “a12b”, “a21b” i “a22b” les dues primeres perquè tenen una repetició d'algun dels elements del conjunt de caràcters definit per [12] i les quatre últimes perquè en tenen dues.


A l'esquerra dels metacaràcters de repetició també hi pot haver una expressió regular, el resultat és el mateix que l'expressió regular que s'obtindria repetint la cadena que defineix l'expressió regular prèvia el nombre de vegades indicat pels metacaràcters de repetició. Per exemple l'expressió regular: “(ab){2,3}” defineix el conjunt de cadenes obtingut per la unió dels conjunts de cadenes que defineixen l'expressió regular “abab” i “ababab” en la primer hi ha dues repeticions i en la segona tres, la primera defineix el conjunt de cadenes amb un únic element, la cadena “abab” i la segona el conjunt amb l'únic element “ababab” i la unió dels dos és el conjunt amb els elements “abab” i “ababab”. Per exemple l'expressió regular: “(a[bc]){1,2}” defineix el conjunt de cadenes obtingut per la unió dels conjunts de cadenes que defineixen l'expressió regular “a[bc]” i “a[bc]a[bc]” en la primer hi ha una repetició i en la segona dues repeticions, la primera defineix el conjunt de cadenes que té per elements “ab” i “ac” i la segona el conjunt amb els elements “abab”, “abac”, “acab” i “acac” i la unió dels dos és el conjunt amb els elements “ab”, “ac”, “abab”, “abac”, “acab” i “acac”.

Ús de les expressions regulars en Python

modifica

Python fa servir les expressions regulars per trobar i substituir subcadenes dins de cadenes.

L'ús més directe consisteix en analitzar si hi ha alguna subcadena d'una cadena donada que pertany al conjunt de cadenes definit per una expressió regular. A més de les expressions explicades fins aquí Python proporciona extensions per forçar que no es considerin com a pertanyents al conjunt determinades subacenes en funció del que hi ha abans o desprès en la cadena original.

Les extensions que ofereix python s'anomenen referències avançades o endarrerides. En una referència avançada la subcadena no es considera que pertanyi al conjunt si la seva continuació no pertany a la referència avançada (o si hi pertany en el cas de referències avançades negatives. En el cas de referències endarrerides és el mateix però per la cadena precedent. Aquestes referencies s'expressen amb la següent sintàxi:

  • Referència avançada positiva: <expressió regular 1>(?=<expressió regular 2>) Només s'accepta la subcadena si el caracters que hi ha a continuació encaixen amb l'expressió regular 2.
  • Referència avançada negativa: <expressió regular 1>(?=|<expressió regular 2>) Només s'accepta la subcadena si el caracters que hi ha a continuació no encaixen amb l'expressió regular 2.
  • Referència endarrerida positiva: (?<=<expressió regular 1>)<expressió regular 2> Només s'accepta la subcadena si el caracters que la precedeixen encaixen amb l'expressió regular 1.
  • * Referència endarrerida negativa: (?<!<expressió regular 1>)<expressió regular 2> Només s'accepta la subcadena si el caracters que la precedeixen no encaixen amb l'expressió regular 2.


PENDENT D'ESCRIURE AMB DETALL:

  • Encaix només despres de newline o bans o al començament de paraula o al final
  • Agrupacinons d'expressions regulars

Per tal d'emprar les expressions regulars, Python ofereix la possibilitat de compilar-les i un cop compilades genera un objecte que té els mètodes per cercar i substituir.

La funció per compilar una expressió regular té la sintaxi següent:

objecte_er_compilada = re.compile(<expressió regular>)

I els mètodes per:

  • Verificar si en una cadena hi ha una subcadena que pertany al conjunt definit per l'expressió regular:
subcadena = objecte_er_compilada.match(cadena)

Retorna la primera subcadena de “cadena” que encaixa amb l'expressió regular compilada a l'objecte “objecte_er_compilada” i la emmagatzema en la variable “subcadena”. Si no n'hi ha cap la subcadena queda buida i dóna fals en comparacions, així es pot emprar en expressions lògiques d'instruccions control del programa.

  • Trobar totes les subcadenes que es poden obtenir a partir d'una cadena donada que encaixin amb una expressió regular.
llista_de_subcadenes = objecte_er_compilada.find(cadena)

Retorna una llista que a cada element hi té una subcadena de “cadena” que encaixa amb l'expressió regular.

El nombre de subcadenes que ha trobat es pot saber amb la funció len:

nombre_de_subcadenes = len(llista_de_subcadenes)

I cada subcadena es pot obtenir traient-la de la llista:

subcadena = llista_de_subcadenes[n]

On n és un nombre natural 0<=n<nombre_de_subcadenes. Fixeu-vos que el primer element de la llista és el 0 i l'últim: nombre_de_subcadenes - 1.

  • Substituir les subcadenes d'una cadena donada que encaixen amb una expressió regular per altres subcadenes.
novacadena=objecte_er_compilada.sub(subcadenaquesubstitueix,cadenavella)

On la "subcadenaquesubstitueix" pot emprar els arguments: \1, \2,... per emprar els bocins de cadena que han encaixat amb les parts de l'expressió regular i per tant reintroduir-les modificades.