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

# Expressions regulars

    Aquest apèndix conté una breu però probablement suficient i
    completa introducció al món de les expressions
    regulars. Les documenta tal com apareixen en
    el &kappname;, 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 cerca normal, s'hauria de començar a cercar el primer nom, «Enric» potser seguit de «di», de la manera següent: `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 cerca, i amb un alt grau de precisió.

Per a aconseguir-ho, les expressions regulars estableixen regles per a 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 fins a 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 l'expressió regular següent:

`^[ \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

L'accent circumflex (`^`) que es troba al començament de l'expressió és una declaració, que tan sols és certa si la resta de la cadena de cerca 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'altre patró conté un primer subpatró que coincideix amb `Enric` o amb `Pere`, després una part de coincidència exacta `di` i, finalment, un altre subpatró que coincideix amb `u` o amb `gué`

La cadena `{0,4}` és un quantificador que diu «en qualsevol lloc des de 0 fins 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 a accedir a aquestes referències, podem posar les nostres mans tant en la cadena coincident completa (quan se 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 l'ú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 l'última secció presentarà una sèrie d'útils exemples.

## Patrons

Els patrons consten de cadenes literals i classes de caràcter. Els patrons poden contenir subpatrons, els quals 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 a 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 inversa (`\`).

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 té 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 mateix caràcter de la barra inversa. 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 dígits tenen un ordre lògic, ho podeu abreujar usant intervals: `[a-c]` és igual que `[abc]` i `[0-9]` és igual que `[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 independent de la caixa de les lletres que coincideixi amb «a» o «b», haureu d'escriure `[aAbB]`.

De manera que és possible crear una classe «negativa» perquè es faci coincidir «tot menys». Per a fer-ho incloeu un accent circumflex (`^`) 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, línia nova 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, dígit o guió baix. És igual que `[a-zA-Z0-9_]`.

`\W`

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

També està admesa la notació POSIX de les classes, `[:<nom classe>:]`. Per exemple, `[:dígit:]` és equivalent a `\d`, i `[:espai:]` a `\s`. Vegeu la llista completa de les classes de caràcters POSIX aquí.

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 \.]`

#### 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 perquè 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 accent circumflex sense escapar).

`^` (accent circumflex)

  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 interval lògic. Haurà d'estar escapat en una classe de caràcter.

`\` (barra inversa)

  El caràcter d'escapada. 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'utilitzar una expressió `Jordi|Albert`.

### Subpatrons

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

#### Especificació d'alternatives

Podeu usar un subpatró per a agrupar un conjunt d'alternatives dins d'un patró més gran. Les alternatives se 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 voleu utilitzar una referència enrere, utilitzeu un subpatró `(PATRÓ)` perquè es recordi la part desitjada del patró. Per a evitar que es recordi el subpatró, utilitzeu un grup sense captura `(?:PATTERN)`.

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 l'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 que el primer. (La cadena `\1` fa referència al primer subpatró delimitat per parèntesis).

Per a evitar ambigüitats amb l'ús de `\1` amb alguns dígits al darrere (&pex;, `\12` pot ser el subpatró 12 o simplement el primer subpatró amb `2`) utilitzarem `\{12}` com a sintaxi per als subpatrons amb múltiples dígits.

Exemples:

- `\{12}1` és «utilitza el subpatró 12»

- `\123` és «utilitza la captura 1 després 23 com a text normal»

#### Declaracions d'anticipació

Una declaració d'anticipació és un subpatró, el qual 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.

Vegeu també, Declaracions.

#### Declaracions de cerca cap enrere

Una declaració de cerca cap enrere és un subpatró, el qual comença per `?<=` o per `?<!`.

La cerca cap enrere té el mateix efecte que l'anticipada, però funciona a l'inrevés. Per exemple, per a fer coincidir la cadena literal «fruit», però només si no està precedida per «grape», podreu utilitzar aquesta expressió: `(?<!grape)fruit`.

Els subpatrons usats en les declaracions no es capturen.

Vegeu 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 inversa)

  El caràcter d'escapada.

`^` (accent circumflex)

  Declara el començament de la cadena.

`$`

  Declara el final de la cadena.

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

  Denota subpatrons.

`{}` (claus dreta i esquerra)

  Denota quantificadors numèrics.

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

  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 interval 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}`

  Zero o 1 ocurrència

`{,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 nombre d'ocurrències.

`+` (signe més)

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

`?` (signe d'interrogació)

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

### Voracitat

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

El programari modern d'expressions regulars proporciona els mitjans per a «desactivar la voracitat», tot i que en els entorns gràfics dependrà de la interfície en tenir accés a aquesta característica. Per exemple, un diàleg de cerca que permeti expressions regulars, podria tenir una casella de selecció anomenada «Coincidència mínima», a més, hi podria haver una indicació que la voracitat és el comportament predeterminat.

### Exemples en context

Aquests són alguns exemples que utilitzen 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 «<elementtancat/>» així com amb «>» en «<elementobert>».

## Declaracions

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

Una declaració no necessita la coincidència d'un caràcter, sinó que investiga els voltants cercant 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í que 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 què 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:

`^` (accent circumflex: 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 de paraula)

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

  Això és 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.

`(?<=PATRÓ)` (cerca cap enrere positiva)

  La cerca cap enrere té el mateix efecte que l'anticipació, però funciona a l'inrevés. Una cerca cap enrere cerca a la part de la cadena anterior a una possible coincidència. La cerca cap enrere positiva només coincidirà amb una cadena si està precedida pel PATRÓ de la declaració, i el text que coincideix amb aquest no serà inclòs en el resultat.

  L'expressió `(?<=cup)cake` coincidirà amb «cake» si està precedit per «cup» (sí a «cupcake» però no a «cheesecake» o «cake»).

`(?<!PATRÓ)` (cerca cap enrere negativa)

  La cerca cap enrere negativa prevé una possible coincidència si la part anterior de la cadena coincideix amb el PATRÓ.

  L'expressió `(?<![\w\.])[0-9]+` coincidirà amb «123» a les cadenes «=123» i «-123» però no coincidirà amb les cadenes «.123» o «word123».

`(PATRÓ)` (amb captura del grup)

  El subpatró dins dels parèntesis serà capturat i recordat, de manera que pugui usar-se en les referències enrere. Per exemple, l'expressió `(&quot;+)[^&quot;]*\1` coincidirà amb `""""text""""` i `"text"`.

  Per a obtenir més informació vegeu Captura del text coincident (referències enrere).

`(?:PATRÓ)` (sense captura del grup)

  El subpatró entre parèntesis no es capturarà ni recordarà. És preferible utilitzar sempre grups sense captura si no s'utilitzaran les captures.