Expressions regulars
Anatomia
Una expressió regular es compon d'elements amb rols ben definits:
/patró/flags — La notació estàndard. Les barres / actuen de delimitadors; els flags controlen el comportament global: g (totes les coincidències), i (insensible a majúscules), m (^/$ per línia), s (. coincideix amb salts de línia).
Metacaràcters — Símbols amb significat especial: . (qualsevol caràcter excepte \n), \d (un dígit), \w (lletra, dígit o _), \s (espai en blanc). Les seves negacions: \D, \W, \S.
Quantificadors — Repeticions: * (0 o més), + (1 o més), ? (0 o 1), {n} (exactament n), {n,m} (entre n i m). Per defecte són greedy; afegint ? es tornen lazy: +?, *?.
Àncores — Posicions sense consumir caràcters: ^ (inici), $ (final), \b (frontera de paraula).
Classes de caràcters — [abc] coincideix amb a, b o c. [a-z] és un rang. [^abc] és la negació.
Grups — (...) agrupa i captura. (?:...) agrupa sense capturar. (?<nom>...) crea captures amb nom. (?=...) i (?!...) són lookaheads.
Alternació — gat|gos coincideix amb "gat" o "gos".
Història i evolució
La teoria matemàtica que sustenta les expressions regulars la va formalitzar el matemàtic Stephen Kleene el 1956. El pas de la teoria a la pràctica el va donar Ken Thompson el 1968, quan va implementar les regex a l'editor ed d'UNIX. El 1973 va crear grep —eina icònica d'UNIX—, el nom de la qual prové de la sintaxi regex: g/re/p (global regular expression print).
Als anys 80, POSIX va estandarditzar les BRE i ERE, que encara s'usen a grep, sed i awk. El punt d'inflexió fonamental va arribar el 1987, quan Larry Wall va dissenyar Perl amb les regex com a element central, creant les PCRE (Perl Compatible Regular Expressions), estàndard de facto adoptat per PHP, Python, Ruby, Java i JavaScript.
El 1997, Philip Hazel va publicar la biblioteca PCRE com a implementació independent. Avui les PCRE2 estan presents en Apache, Nginx, PostgreSQL i pràcticament totes les eines del món digital.
Bones pràctiques
Prova sempre amb dades reals i casos límit. Una regex vàlida per a 3 exemples pot fallar amb dades reals imprevistes. Prova amb casos vàlids, de frontera i intencional·ment incorrectes.
Ancora quan sigui possible. Usar ^ i $ redueix el temps de cerca i evita coincidències parcials no previstes.
Evita el backtracking catastròfic. Patrons com (a+)+ sobre cadenes llargues poden trigar temps exponencial i bloquejar un servidor (ReDoS). Evita quantificadors nidificats sobre els mateixos caràcters.
Usa grups no capturadors (?:...) per defecte. Si no necessites la captura per a referència posterior, (?:...) és més eficient i deixa clar que el grup és estructural.
Comenta les regex complexes. En Python i PHP el flag (?x) (verbose mode) permet afegir espais i comentaris dins del patró.
Errors comuns
Oblidar escapar el punt. . significa "qualsevol caràcter", no un punt literal. Cal escriure \. per al punt literal. L'expressió /helpi.top/ coincideix amb "helpiXtop" igual que amb "helpi.top".
Greedy vs lazy mal aplicat. <.*> sobre <b>text</b> captura tot el fragment. La versió lazy <.*?> captura cada etiqueta individualment.
Oblidar el flag g. Sense g, string.match(/patró/) a JavaScript retorna només la primera coincidència.
Backtracking catastròfic. El patró (a+)+b pot trigar temps exponencial sobre "aaaaaaaaac". Explotable per bloquejar serveis (ReDoS).
Assumir que . inclou salts de línia. Per defecte no ho fa. Cal el flag s o usar [\s\S].
Usar regex per a HTML o JSON. És un anti-patró: fràgil davant nidificació. Per a formats estructurats, usa parsers especialitzats.
Casos d'ús
Validació de formularis. Emails, telèfons, codis postals, NIF: les regex validen el format al client i al servidor simultàniament.
Anàlisi de logs. Amb regex pots extreure IPs, codis HTTP, timestamps o errors concrets de milions de línies de log en pocs segons.
Find & replace avançat en editors. VS Code, Vim i Sublime Text suporten regex en cerca/substitució. Pots renomenar 500 variables o reformatar dates en un CSV de 100.000 files amb una sola operació.
Routing en frameworks web. Rails, Laravel, Django i Express defineixen les seves rutes amb patrons que capturen paràmetres de l'URL.
Processat de dades i ETL. Les regex extreuen camps de formats no estructurats per normalitzar-los i carregar-los a bases de dades.
Curiositats
- El nom grep prové de la comanda <code>:g/re/p</code> de l'editor <code>ed</code> d'UNIX (1973): "global regular expression print". La seva creació per Ken Thompson va posar les regex a l'abast de qualsevol usuari UNIX.
- El fenomen ReDoS (Regular Expression Denial of Service) ha causat outages reals: el 2016, una regex amb backtracking catastròfic va bloquejar Stack Overflow durant 34 minuts en producció.
- RFC 5322, l'estàndard formal d'adreces de correu, es pot validar completament amb una regex... però el resultat té 6.318 caràcters. Per a ús pràctic, una regex de 50-100 caràcters cobreix el 99,9% dels casos.
- XKCD va publicar el còmic #208 "Regular Expressions" el 2007. A dia d'avui és la referència cultural central de la comunitat programadora sobre regex.