&Anders.Lund; &Anders.Lund.mail;
Antoni
Bella

    bella5@teleline.es

Traductor

# Expressions regulars

    Aquest apèndix conté una breu però probablement suficient i
    completa introducció al món de les expressions
    regulars. Les documenta tal i com apareixen en
    el &kate;, donat que no són compatibles amb les expressions
    regulars de perl, ni de grep, per exemple.

## Introducció

Les expressions regulars us proporcionen un mètode per a descriure el possible contingut d'una cadena de text de manera que pugui ser interpretada per una petita peça de programari, i d'aquesta manera es pugui esbrinar si un text es correspon amb el cercat i, en el cas d'aplicacions avançades, es posin els mitjans per a recuperar parts del text coincident.

Per exemple: Posem que voleu cercar un text que és el començament d'un paràgraf que inclou els noms Enric o Pere, seguits d'alguna forma del verb dir.

En una recerca normal, s'hauria de començar a cercar pel primer nom, Enric potser seguit de di, de la següent manera: `Enric di`, i mentre cerca coincidències, haureu de descartar aquelles que no estiguin al començament d'un paràgraf, així com aquelles en les que la paraula que comenci per di que no pertanyi al verb dir. I després tornar a repetir tot el procés amb el següent nom...

Amb les expressions regulars, aquesta tasca s'hauria de realitzar d'una sola recerca, i amb un alt grau de precisió.

Per a aconseguir-ho, les expressions regulars estableixen regles per expressar amb detall una generalització de la cadena a cercar. El nostre exemple el podríem expressar literalment com: Una línia que comença per Enric o per Pere (possiblement després de 4 espais en blanc o tabulacions) seguit d'un espai en blanc seguit de di i després u o gué, es podria expressar amb la següent expressió regular:

`^[ \t]{0,4}(Enric|Pere) di(u|gué)`

L'exemple anterior mostra els quatre conceptes principals de les expressions regulars modernes, a veure:

- Patrons

- Declaracions

- Quantificadors

- Referències enrere

El barret (`^`) que es troba al començament de l'expressió és una declaració, que tan sols és certa si la resta de la cadena de recerca es troba al començament d'una línia.

Les cadenes `[ \t]` i `(Enric|Pere) di(u|gué)` són patrons. El primer és una classe de caràcters que coincideix amb un espai en blanc o amb una tabulació (horitzontal); l'altra patró conté un primer subpatró que coincideix amb `Enric` o amb `Pere`, després una part de coincidència exacta `di` i per últim un altra subpatró que coincideix amb `u` o amb `gué`

La cadena `{0,4}` és un quantificador que diu en qualsevol lloc des de 0 a 4 caràcters anteriors.

Com el programari d'expressions regulars suporta el concepte de referències enrere desa tota la part coincident de la cadena així com els subpatrons tancats entre parèntesis, proporcionant mitjans per accedir a aquestes referències, podem posar les nostres mans tant en la cadena coincident completa (quan es cerca al text d'un editor mitjançant una expressió regular, que normalment apareix marcada com a seleccionada) com en el nom trobat, o en la última part del verb.

Unint-ho tot, l'expressió coincidirà a on nosaltres vulguem, i tan sols allí.

Les següents seccions descriuen amb detall com construir i usar patrons, classes de caràcters, declaracions, quantificadors i referències enrere, i la última secció presentarà una serie d'útils exemples.

## Patrons

Els patrons consten de cadenes literals i classes de caràcter. Els patrons poden contenir subpatrons, que són patrons tancats entre parèntesis.

### Caràcters d'escapada

En els patrons, així com en les classes de caràcter, alguns caràcters tenen un significat especial. Per aconseguir una coincidència literal amb algun d'aquests caràcters, és necessari marcar-los com a escapats per a permetre a l'intèrpret d'expressions regulars comprendre que aquests caràcters han de ser inclosos en el seu significat literal.

Això es fa precedint el caràcter d'una barra invertida (`\`).

El programari d'expressions regulars ignorarà l'escapat de qualsevol caràcter que no tingui cap significat especial en el context, així que escapar, per exemple, j (`\j`) no te per què causar problemes. Si teniu cap dubte sobre quan un caràcter pot tenir un significat especial, escapeu-lo amb seguretat.

L'escapat inclou el propi caràcter de la barra invertida. Per a poder presentar-la de forma literal, heu d'escriure `\\`.

### Classes de caràcter i abreujaments

Una classe de caràcter és una expressió que coincideix amb un conjunt de caràcters definit. En les expressions regulars, les classes de caràcter s'estableixen col·locant els caràcters vàlids de la classe entre claudàtors `[]`, o usant una de les classes abreujades que es descriuen a continuació.

Les classes de caràcters simples tan sols contenen un o més caràcters literals, per exemple `[abc]` (que coincidirà amb les lletres a, b o c) o `[0123456789]` (que coincidirà amb qualsevol dígit).

Com les lletres i els números tenen un ordre lògic, ho podeu abreujar usant rangs: `[a-c]` és igual a `[abc]` i `[0-9]` és igual a `[0123456789]`. Combinant aquestes construccions, per exemple `[a-fynot1-38]` resulta completament vàlid (aquesta última hauria de coincidir amb qualsevol dels caràcters o dígits a, b, c, d, e, f, y, n, o, t, 1, 2, 3 o 8).

Com les lletres majúscules són caràcters diferents que els seus equivalents en minúscula, per a crear una classe de caràcter que sigui independent del format de les lletres, haureu d'escriure `[aAbB]`.

De manera que és possible crear una classe negativa per a que es faci coincidir tot menys. Per a fer-ho inclogueu un barret (`^`) al començament de la classe:

`[^abc]` coincidirà amb qualsevol caràcter excepte amb a, b o c.

A més dels caràcters literals, hi ha alguns abreujaments definits, per a facilitar una mica les coses:

`\a`

  Aquest coincideix amb el caràcter ASCII del timbre (BEL, 0x07).

`\f`

  Aquest coincideix amb el caràcter ASCII del salt de pàgina (FF, 0x0C).

`\n`

  Aquest coincideix amb el caràcter ASCII del salt de línia (LF, 0x0A, nova línia a Unix).

`\r`

  Aquest coincideix amb el caràcter ASCII de retorn de carro (CR, 0x0D).

`\t`

  Aquest coincideix amb el caràcter ASCII del tabulador horitzontal (HT, 0x09).

`\v`

  Aquest coincideix amb el caràcter ASCII del tabulador vertical (VT, 0x0B).

`\xhhhh`

  Aquest coincideix amb el caràcter Unicode corresponent al número hexadecimal hhhh (entre 0x0000 i 0xFFFF). \0ooo (&ead;, \zero ooo) coincideix amb el caràcter ASCII/Latin-1 corresponent al número octal ooo (entre 0 i 0377).

`.` (punt)

  Aquest coincideix amb qualsevol caràcter (inclòs el de nova línia).

`\d`

  Aquest coincideix amb un dígit. És igual que `[0-9]`

`\D`

  Aquest coincideix amb un no dígit. És igual que `[^0-9]` o `[^\d]`

`\s`

  Aquest coincideix amb un caràcter d'espai en blanc. Pràcticament igual que `[\t\n\r]`

`\S`

  Aquest coincideix amb un no espai en blanc. Pràcticament igual que `[^\t\r\n]`, i igual que `[^\s]`

`\w`

  Coincideix amb qualsevol caràcter d'una paraula, en aquest cas qualsevol lletra o número. Tingueu present que el subratllat (`_`) no hi estarà inclòs, a diferència de les expressions regulars de perl. És igual que `[a-zA-Z0-9]`.

`\W`

  Coincideix amb qualsevol caràcter que no sigui una paraula, qualsevol cosa menys lletres o números. És igual que `[^a-zA-Z0-9]` o `[^\w]`.

Les classes abreujades es poden posar a dins d'una classe pròpia, per exemple per a fer coincidir un caràcter d'una paraula, un espai en blanc o un punt, podeu escriure `[\w \.]`

La notació POSIX de classes, `[:<class name>:]` actualment no està suportada.

#### Caràcters amb significat especial dintre de les classes de caràcters

Els següents caràcters tenen un significat especial dintre de la construcció de classes dels caràcters [], i és necessari escapar-los per a que siguin inclosos literalment en una classe:

`]`

  Finalitza la classe de caràcters. Haurà d'estar escapat excepte si és el primer caràcter de la classe (pot seguir a un barret sense escapar).

`^` (barret)

  Indica que es tracta d'una classe negativa, si és el primer caràcter. Haurà d'estar escapat per a cercar una coincidència literal en el cas que sigui el primer caràcter en la classe.

`-` (guió)

  Indica un rang lògic. Haurà d'estar escapat en una classe de caràcter.

`\` (barra invertida)

  El caràcter de escape. Haurà d'estar sempre escapat.

### Alternatives: Coincidències amb un de

Si desitgeu que la coincidència sigui una d'una sèrie de patrons alternatius, els podeu separar amb `|` (caràcter de barra vertical).

Per exemple, per a trobar Jordi o Albert, hauríeu d'usar una expressió `Jordi|Albert`.

### Subpatrons

Els subpatrons són patrons tancats entre parèntesis, i tenen diversos usos en el mon de les expressions regulars.

#### Especificació d'alternatives

Podeu usar un subpatró per agrupar un conjunt d'alternatives dins d'un patró més gran. Les alternatives es separen amb el caràcter | (barra vertical).

Per exemple, per a cercar la coincidència de les paraules int, float o double, es podria usar el patró `int|float|double`. Si tan sols desitgeu trobar-ne una seguida d'algun tipus d'espai en blanc i després algunes lletres, poseu les alternatives dins d'un subpatró: `(int|float|double)\s+\w+`.

#### Captura del text coincident (referències enrere)

Si desitgeu usar una referència enrere, useu un subpatró per a que es recordi la part desitjada del patró.

Per exemple, si desitgeu trobar dues ocurrències de la mateixa paraula separades per una coma i possiblement algun espai en blanc, podeu escriure `(\w+),\s*\1`. El subpatró `\w+` localitzarà un conjunt de caràcters d'una paraula, i tota la expressió coincidirà si aquest conjunt va seguit d'una coma, 0 o més espais en blanc i després un conjunt de caràcters d'una paraula igual al primer. (La cadena `\1` fa referència al primer subpatró delimitat per parèntesis)

#### Declaracions d'anticipació

Una declaració d'anticipació és un subpatró, que comença per `?=` o per `?!`.

Per exemple, si voleu cercar la cadena literal Bill, però tan sols si no va seguida de Gates, podeu usar l'expressió: `Bill(?! Gates)`. (Això coincidirà amb Bill Clinton i amb Billy el nen, però ignoraria en silenci les altres coincidències).

Els subpatrons usats en les declaracions no es capturen.

Veure també Declaracions.

### Caràcters amb un significat especial dins dels patrons

Els següents caràcters tenen significat dins dels patrons, i és necessari escapar-los per a una coincidència literal:

`\` (barra invertida)

  El caràcter d'escapada.

`^` (barret)

  Declara el començament de la cadena.

`$`

  Declara el final de la cadena.

`()` (parèntesis dret i esquerra)

  Denota subpatrons.

`{}` (claus dreta i esquerra)

  Denota quantificadors numèrics.

`[]` (claudàtors dret i esquerra)

  Denota classes de caràcter.

`|` (barra vertical)

  O lògic. Separa alternatives.

`+` (signe més)

  Quantificador, 1 o més.

`*` (asterisc)

  Quantificador, 0 o més.

`?` (signe d'interrogació)

  Un caràcter opcional. Es pot interpretar com quantificador, 0 o 1.

## Quantificadors

Els quantificadors permeten que una expressió regular coincideixi amb un número o un rang de números de qualsevol caràcter, una classe de caràcter o un subpatró.

Els quantificadors es col·loquen entre claus (`{` i `}`). Teniu la forma general `{[ocurrències-mínimes][,[ocurrències-màximes]]}`

L'ús s'explica millor en aquest exemple:

`{1}`

  Exactament 1 ocurrència

`{0,1}`

  Cero o 1 ocurrències

`{,1}`

  El mateix, però amb menys treball ;)

`{5,10}`

  Com a mínim 5 i com a màxim 10 ocurrències.

`{5,}`

  Com a mínim 5 ocurrències, sense màxim.

A més, hi ha alguns abreujaments:

`*` (asterisc)

  Similar a `{0,}`, troba qualsevol número d'ocurrències.

`+` (signe més)

  Similar a `{1,}`, almenys 1 ocurrència.

`?` (signe d'interrogació)

  Similar a `{0,1}`, cero o 1 ocurrència.

### Avarícia

Quan s'usen quantificadors sense màxim, les expressions regulars intenten coincidir amb la major part possible de la cadena cercada, coneguen-se aquest comportament com a avariciós.

El programari modern d'expressions regulars proporciona els mitjans per a desactivar l'avarícia, tot i que en els entorns gràfics dependrà de la interfície al tenir accés a aquesta característica. Per exemple, un diàleg de recerca que permeti expressions regulars, podria tenir una casella de comprovació anomenada Coincidència mínima. A més hi podria haver una indicació quant a que el comportament per omissió és d'avarícia.

### Exemples en context

Aquests són alguns exemples que usen quantificadors:

`^\d{4,5}\s`

  Coincideix amb els dígits en 1234 ja i 12345 ara, però no amb els de 567 onze ni els de 223459 enlloc.

`\s+`

  Coincideix amb un o més espais en blanc.

`(bla){1,}`

  Coincideix amb blablabla i amb el bla de blanc o tabla.

`/?>`

  Coincideix amb /> en <ítemtancat/> així com amb > en <ítemobert>.

## Declaracions

Les declaracions permeten que una expressió regular tan sols coincideixi sota una sèrie de condiciones controlades.

Una declaració no necessita la coincidència d'un caràcter, si no que investiga els voltants en recerca d'una possible coincidència abans de donar-la per vàlida. Per exemple, la declaració límit de paraula no intenta trobar un caràcter que no sigui d'una paraula en oposició a un que sí estigui en la seva posició, en comptes d'això mira d'assegurar que no és un caràcter d'una paraula. Això vol dir que la declaració pot ser vàlida en el cas que no hi hagi cap caràcter, &ead;, al final de la cadena cercada.

Algunes declaracions actuals no tenen un patró amb el que coincidir, però la part coincident de la cadena no serà part del resultat de la coincidència de l'expressió completa.

Les expressions regulars aquí documentades suporten les següents declaracions:

`^` (barret: el començament d'una cadena)

  Coincideix amb el començament de la cadena cercada.

  L'expressió `^Pere` coincidirà amb Pere en la cadena Pere, hola! però no en Hola Pere!

`$` (final de la cadena)

  Coincideix amb el final de la cadena cercada.

  L'expressió `tu\?$` coincidirà amb el final de la cadena No l'has fet tu?, però amb cap part de Tu no l'has fet?

`\b` (límit d paraula)

  Coincideix si hi ha un caràcter de paraula a un costat i un altra que no sigui a l'altra.

  Això es molt útil per a trobar el final de les paraules, o ambdós extrems per a delimitar tota la paraula. L'expressió `\bin\b` coincidirà amb el in separat en la cadena He came in through the window, però no amb el in de window.

`\B` (no límit de paraula)

  Coincideix amb tot el que \b no coincideix.

  Això vol dir que coincidirà, per exemple, dins de les paraules: L'expressió `\Bin\B` coincidirà en window però no en integer o en I'm in love.

`(?=PATRÓ)` (Anticipació positiva)

  Una declaració d'anticipació cerca la part de la cadena seguida d'una possible coincidència. L'anticipació positiva prevé la coincidència de la cadena si el text que segueix no correspon al PATRÓ de la declaració, i el text que coincideix amb aquest no serà inclòs en el resultat.

  L'expressió `handy(?=\w)` coincidirà amb handy en handyman però no en That came in handy!

`(?!PATRÓ)` (Anticipació negativa)

  L'anticipació negativa prevé una possible coincidència si la següent part de la cadena coincideix amb el PATRÓ.

  L'expressió `const \w+\b(?!\s*&)` coincidirà amb const char en la cadena const char* foo, mentre que no coincidirà amb const QString en const QString& bar, atès que el & coincideix amb el patró de la declaració d'anticipació negativa.