Guida italiana all'uso del Perl-compatible regular expression ============================================================= Versione 0.2 del 19 aprile 2000 Curatore: eaglestorm@iname.com (EagleStorm) Ringraziamenti per i preziosi contributi: Carlo Fusco Autori aventi pubblicazioni tradotte all'interno della guida Philip Hazel Carl Franklin e Gary Wisniewski inoltre voglio anche ringraziare tutte quelle persone che, pur avendo contribuito con importanti suggerimenti e correzioni alla stesura del presente documento, hanno manifestato il desiderio di rimanere anonimi. Distribuzione: Usenet: posting periodico su it.faq e it.comp.software.newsreader web: http://www.geocities.com/fashionavenue/1075/pcre.txt Licenza d'uso ed altre avvertenze: Questo documento viene rilasciato secondo la licenza GNU General Public License (GPL o copyleft) versione 2 della Free Software Foundation. Chiunque è autorizzato a distribuire copie elettroniche o cartacee del presente documento, allegarlo a raccolte, CD-ROM o programmi, a patto di citare la fonte da cui è stato tratto. Inoltre il presente documento può essere liberamente modificato in ogni sua parte purché venga rilasciato secondo la medesima licenza e i nomi dei curatori della presente versione vengano rimossi. L'autore non si assume _NESSUNA_ responsabilità per eventuali errori o inesattezze. ATTENZIONE: la maggior parte di questo documento fa riferimento a traduzioni semi integrali di quanto già pubblicato in lingua anglosassone sul Perl-Compatible Language Expression. Questa guida è stata realizzata per puro spirito volontaristico e senza alcun intento economico. History: V 0.1: Guida italiana all'uso del Perl-compatible regular expression Indice degli argomenti: -Prefazione -Cosa bisogna sapere prima di leggere questo documento Sezione 1: Il PCRE-style regular expression 1.1 A cosa serve il PCRE-style regular expression? 1.2 Cos'è il PCRE-style regular expression? 1.3 I metacaratteri 1.4 Meta-carattere "\" (backslash) 1.5 Meta-caratteri "^" e "$". Accento circonflesso e dollaro. 1.6 Meta-carattere "[" ("]"). Le classi di carattere. 1.7 Meta-carattere "|". Le alternative. 1.8 Modalità interne al PCRE (internal option setting). 1.9 I sotto modelli (subpattern) 1.10 Le ripetizioni 1.11 Back Reference 1.12 Le asserzioni 1.13 Subpattern per una volta sola (once-only) 1.14 Subpattern condizionate 1.15 Commenti 1.16 Credits Sezione 9: Espressioni regolari - Perl Regular Expression Tutorial 2.1 Introduzione al tutorial PCRE 2.2 Semplici esempi di espressioni regolari 2.3 Metacaratteri 2.4 Caratteri riservati 2.5 Cose da ricordare Prefazione ---------- Questo documento ha l'ambizione di colmare almeno parzialmente la l'assenza di informazioni in lingua italiana disponibili in rete sulla funzionamento del Perl-Compatible Language Expression. Cosa bisogna sapere prima di leggere questo documento ----------------------------------------------------- Questa guida si pone come complemento per una conoscenza approfondita di tutti i prodotti software che impiegano espressioni regolari per effettuare ricerche. Il modo in cui il p-cre è stato implementato all'interno di questi prodotti esula dagli obiettivi qui definiti. E' da considerarsi quindi buona norma, prima di affrontare questa guida, comprendere in dettaglio come possano essere introdotte le espressioni regolari al loro interno. Sezione 1: Il PCRE-style regular expression ------------------------------------------- 1.1 A cosa serve il PCRE-style regular expression? Il PCRE-style regular expression estende notevolmente la potenza delle tecniche di scoring di Hamster. In altri termini, offre la possibilità di includere alternative e ripetizioni allargando o restringendo l'intervallo di corrispondenza nel novero delle stringhe o dei valori possibili. Un semplice esempio concernente i filtri sulle repliche è già stato illustrato al punto 7.7. Il modello {^Re:\s|^R:\s} è in grado di filtrare tutte le stringhe che iniziano per "Re: " o per "R: ". Questo modello non è in alcun modo riproducibile a meno di non utilizzare interfacce complesse (es. alcuni motori di ricerca) o potenti motori procedurali come il PCRE-style. Senza PCRE-style, Hamster non sarebbe in grado di filtrare questo tipo di contenuti. La stessa cosa è stata compresa da altri sviluppatori che hanno adottato il PCRE-style nei loro software. Tra questi programmi posso ricordare Pegasus-mail, The Bat!, Xnews ed Agent. 1.2 Cos'è il PCRE-style regular expression? La PCRE library è un set di funzioni che implementano espressioni regolari con condizioni da soddisfare usando la stessa sintassi e semantica del Perl 5 (con qualche piccola differenza). L'implementazione corrente corrisponde al Perl 5.005. Hamster fa uso del Philip Hazel's PCRE package. Questo punto è una versione molto condensata della pagina originale sul PCRE. Non appaiono le sezioni sulla programmazione dell'interfaccia e sulle differenze tra il Perl regex e il PCRE. Una espressione regolare è una condizione, o un modello di condizioni, che deve essere soddisfatta da una stringa, partendo da sinistra verso destra. La maggior parte dei caratteri valgono di per sé in un modello, e misurano o soddisfano i corrispondenti caratteri oggetto della nostra attenzione. Con un esempio terra-terra, possiamo avere: The quick brown fox che misura una porzione di stringa che è identica a se stessa. Il potere delle regular expression deriva dall'abilità di includere alternative e ripetizioni nel modello. Queste sono codificate nel modello attraverso l'uso di "meta-caratteri", i quali non valgono di per sé, ma sono interpretati secondo modalità particolari. 1.3 I metacaratteri Ci sono due differenti set di meta-caratteri: quelli che sono riconosciuti ovunque nel modello (ad eccezione di quando sostano all'interno di parentesi quadre, ovvero di una classe) e quelli che sono riconosciuti nelle parentesi quadre. Al di fuori delle parentesi quadre, i meta-caratteri sono come segue: \ carattere generico "escape", con diversi usi ^ corrisponde l'inizio della stringa (oppure di una riga, in modalità multiline) $ corrisponde la fine della stringa (oppure di una riga, in modalità multiline) . misura ogni carattere ad eccezione delle nuove righe (predefinito) [ inizia una definizione di classe di un carattere | inizia un ramo alternativo ( inizia un sub modello ) termina un sub modello ? estende il significato di ( anche 0 oppure 1 quantità anche "quantifier minimizer" * 0 or more quantifier + 1 oppure più quantità { inizia min/max quantità La parte di un modello che si trova tra parentesi quadre viene identificata come "classe di caratteri". In una classe di caratteri gli unici meta-caratteri sono: \ carattere generico "di fuga" (escape ] terminatore della classe 1.4 Meta-carattere "\" (backslash) Ha diversi significati e funzioni. Per prima cosa se seguito da un carattere non alfa-numerico, elimina ogni significato speciale che il carattere può avere. Questo uso del backslash come carattere di fuga è valido sia all'interno che all'esterno delle classi di carattere "[...]" Per esempio, se si vuole misurare il carattere "*", scriveremo "\*" nel modello. Questa corrispondenza si verifica comunque, anche nel caso in cui il carattere successivo non appartenga all'elenco dei metacaratteri. Quindi qualsiasi carattere non-alfanumerico preceduto da "\" misura se stesso. In particolare, se si vuole proprio corrispondere un backslash, scriveremo "\\". Se un modello è compilato con l'opzione PCRE_EXTENDED, i caratteri spazio " " nel modello (oltre che nelle classi di carattere) e tutti i caratteri tra "#" e il carattere di riga successiva (# serve infatti per inserire i commenti) saranno ignorati. In questo caso, un backslash può essere impiegato se abbiamo l'esigenza di includere un carattere spazio o un carattere # come parte del modello. Con Hamster, per corrispondere esattamente un subject di questo tipo "#free pictures", ricorreremo a questo ScorePattern: {^\#free\spictures$} dove: ^ corrisponde l'inizio stringa \# corrisponde "#" \s corrisponde un carattere di spazio (vi ricordate "^Re:\s"?) $ corrisponde la fine della stringa Un secondo uso del backslash sta nel codificare i caratteri non visibili (printing a video) in un modo comprensibile. Non ci sono restrizioni sulla sostituzione dei caratteri non visibili, a eccezione dello zero binario (1 bit) che termina il modello. Quando un modello viene preparato da un editor di testo, è solitamente più facile usare un elemento della seguente sequenza piuttosto che il rispettivo carattere binario: \a carattere BEL (suono) (hex 07) \cx "control-x", dove x è un carattere \e escape (hex 1B) \f formfeed (hex 0C) \n nuova riga (hex 0A) \r ritorno a capo (hex 0D) \t tabulazione (hex 09) \xhh carattere con codice esadecimale hh \ddd carattere con codice ottale ddd, oppure backreference Il preciso effetto di "\cx" è come segue: il sesto bit coincide con lo spartiacque tra i primi 64 caratteri e quelli successivi fino al settimo bit, ovvero 128. Il valore di x viene invertito in modo semi-speculare e riportato nell'altra metà. Unica eccezione, se "x" è una lettera minuscola viene convertita in maiuscola. Così "\cz" diventerà (26) hex 1A (z ->Z ->5a ->90 90-64=26), mentre "\c{" diventerà (59) hex 3b ({ ->{ ->7b ->123 123-64=59), mentre "\c;" diventerà (123) hex 7b (; ->; ->3b ->59 59+64=123). Dopo "\0" fino a due ulteriori cifre ottali possono essere lette. In entrambi i casi, se ci sono meno di due cifre, saranno usate solo quelle presenti. Così, la sequenza "\0\x\07" specifica due zero binari seguiti da un carattere BEL. Assicuratevi di fornire due cifre dopo lo zero iniziale se il carattere che segue fosse anche esso una cifra ottale. Il trattamento di un backslasch seguito da una cifra diversa da 0 è complicato. Al di fuori di una classe di caratteri, il PCRE lo legge con le cifre successive come numero decimale. Se il numero è inferiore a 10, o se ci sono almeno altrettanti parentesi (...) nell'espressione, l'intera sequenza viene considerata come back reference. Una descrizione di come questa lavori viene fornita nei punti successivi, seguendo il filo conduttore della discussione dei sub-modelli racchiusi nelle parentesi. Per il momento può bastare questo esempio di subpattern con back reference: "(\b\w+\b) to \1" Dentro a una classe di caratteri, oppure se il numero decimale è più grande di 9 e in precedenza non si riscontra un numero di subpattern sufficiente a realizzare una back reference, il PCRE rilegge fino a tre cifre ottali seguite da backslash, e genera un byte singolo dagli ultimi significativi 8 bit (0-255) del valore in poi. Ogni ulteriore cifra vale per se stessa. Per esempio: \040 corrisponde a un altro modo di scrivere uno spazio \40 è la stessa cosa, ammesso che non ci siano 40 precedenti subpattern \7 corrisponde sempre a una back reference \11 potrebbe essere una back reference oppure un altro modo di scrivere tab \011 corrisponde sempre una tabulazione \0113 corrisponde a una tabualazione seguita dal carattere "3" \113 è il carattere con valore ottale 113 (dato anche che non ci possono essere più di 99 back reference) \377 è un byte che equivale a un bit \81 è una back reference o uno zero binario seguito dai due caratteri "8" e "1" I valori ottali di 100 o più grandi non devono essere preceduti da uno zero iniziale perché non vengono comunque lette più di tre cifre. Tutte le sequenze che definiscono un byte singolo possono essere usate sia dentro che fuori le classi di carattere. In aggiunta, dentro una classe di caratteri, la sequenza "\b" viene interpretata come carattere backspace (spazio barra spaziatrice, hex 08). Al di fuori di una classe di caratteri ha un significato particolare (leggi oltre). Il terzo uso del backslash è per specificare alcuni tipi di caratteri generici: \s ogni spazio bianco \S ogni carattere che non è uno spazio bianco \w parola formata solo da caratteri alfanumerici più "_" \W il complemento a \w Ogni coppia di queste quattro sequenze partiziona il set completo dei caratteri in due set distinti. Ogni dato carattere ne corrisponde uno, e solo uno, di ogni coppia. \w corrisponde a ogni lettera o cifra più il carattere "_" (underscore o sottolineatura), e cioè, ogni carattere che può fare parte di una "parola" Perl. La definizione di lettere e cifre viene controllata attraverso la tavola dei caratteri PCRE e, potrebbe variare nel caso in cui una venisse applicata una specifica tabella locale (leggi supporto locale, sopra). Per esempio, in Francia (locale fr) o in Italia (locale it), alcuni codici di carattere più grandi di 128 sono usati per le lettere accentate, e questi sono corrisposti con \w. Questi tipi di sequenze possono apparire sia dentro che al di fuori di una classe di caratteri. Corrispondono unicamente un carattere del tipo appropriato. Se il punto di corrispondenza corrente è alla fine della stringa, il loro impiego fallirà dato che non esistono caratteri da corrispondere. Il quarto uso di un backslash è per alcuni tipi di semplici asserzioni. Un asserzione specifica una condizione che deve essere soddisfatta in un punto particolare della stringa, senza corrispondere alcun carattere della stringa. L'uso di subpattern per asserzioni più complicate è descritto più sotto. Le asserzioni con backslash sono \b confine o punto estremo (inizio/fine) di parola \B non è un confine di parola \A inizio della stringa (indipendente alla modalità multiriga) \Z fine della stringa o della nuova riga (indipendente dalla modalità multiriga) \z fine della stringa (indipendente dalla modalità multiriga) Queste asserzioni non possono apparire in una classe di caratteri (ma osserva che "\b" ha un significato differente, letteralmente il carattere backspace, come abbiamo visto in precedenza, dentro a una classe di caratteri). Un confine di parola corrisponde alla posizione nella stringa dove il carattere corrente e quello precedente non corrispondono rispettivamente né \w, né \W (altrimenti uno corrisponderebbe \w, mentre l'altro \W), oppure l'inizio o la fine di una stringa se il primo o l'ultimo carattere corrisponde \w, rispettivamente. Le asserzioni \A, \Z, e \z differiscono dai tradizionali "^" e "$" (descritti sotto) nel fatto che essi corrispondono all'inizio vero e proprio, e alla fine, della stringa, qualsiasi modalità PCRE venga impostata. xxx 1.5 Meta-caratteri "^" e "$". Accento circonflesso e dollaro. Al di fuori di una classe di caratteri, nella modalità di corrispondenza predefinita, il carattere "^" (accento circonflesso) è un'asserzione che è vera solo se il punto di corrispondenza corrente è all'inizio della stringa. Dentro una classe di caratteri, "^" ha un significato completamente diverso (leggi sotto). L'accento circonflesso non ha bisogno di essere il primo carattere del modello se viene implicato un numero di alternative, ma dovrebbe essere il primo elemento in ogni alternativa in cui appare, ammesso che il modello debba corrispondere quel ramo. Se tutte le possibili alternative cominciano con un accento circonflesso, ovvero se il modello è obbligato a corrispondere solo all'inizio della stringa, si ha un modello ancorato. (Esistono altri tipi di costruzione che possono ancorare un modello). Il carattere "$" (dollaro) è un'asserzione vera solo se il punto di corrispondenza corrente si trova alla fine della stringa, o immediatamente prima di un carattere di nuova riga che è l'ultimo carattere del modello nella stringa (predefinito). Il dollaro non ha bisogno di essere l'ultimo carattere del modello se viene implicato un numero di alternative, ma dovrebbe essere l'unico elemento in un ogni ramo in cui appare. Il dollaro non ha un significato speciale in una classe di caratteri. Il significato del dollaro può essere cambiato in modo da corrispondere solo la fine esatta della stringa (niente più "$" nelle alternative) impostando l'opzione PCRE_DOLLAR_ENDONLY al momento compilazione o della verifica della corrispondenza. Questo non influenza l'asserzione \Z. Il significato di "^" e di "$" cambia se viene impostata l'opzione PCRE_MULTILINE (modalità multiriga). In questo caso, essi rispettivamente corrispondono immediatamente dopo e immediatamente prima un asserzione interna "\n", oltre alla corrispondenza alla fine e all'inizio della stringa. Per esempio, il modello /^abc$/ corrisponde la stringa "dev\nabc" in modalità multiriga, ma non diversamente (ovviamente "\n" nella stringa equivale alla nuova riga). Conseguentemente i modelli che risultano ancorati in modalità monoriga avendo tutti i rami che cominciano con "^" non sono più ancorati in modalità multiriga. Attenzione: l'opzione PCRE_DOLLAR_ENDONLY viene ignorata se viene impostata quella PCRE_MULTILINE. Osservate come le sequenze \A, \Z, e \z possano essere impiegate per corrispondere l'inizio o la fine della stringa in entrambe le modalità. Se tutti i rami del modello cominciano con \A, esso è sempre ancorato, sia che la modalità PCRE_MULTILINE sia attivata o che non lo sia. Al di fuori di una classe di caratteri, un punto nel modello corrisponde ogni singolo carattere della stringa, compresi quelli non visibili (printing a video), tranne (predefinito) quello di nuova riga ("\n"). Se viene impostata l'opzione PCRE_DOTALL, i punti corrispondono anche le nuove righe. Il trattamento di un punto è completamente indipendente dal trattamento dei caratteri "^" e "$", con la sola relazione che sono entrambi possono concernere caratteri di nuova riga. Il punto non ha significati particolari in una classe di caratteri. 1.6 Meta-carattere "[" ("]"). Le classi di carattere. Un parentesi quadra di apertura introduce una classe di caratteri, terminata da una successiva parentesi quadra di chiusura. Una parentesi quadra chiusa, in sé, non ha un significato particolare. Se si richiede una parentesi quadra chiusa come membro della classe, deve essere il primo carattere nella classe (dopo un accento circonflesso, se presente) o sottratta con uno backslash. Una classe di caratteri corrisponde un singolo carattere nella stringa; il carattere deve essere nel set dei caratteri definiti dalla classe, a meno che il primo carattere nella classe non sia un accento circonflesso "^", nel qual caso il carattere della stringa non deve essere nel set definito dalla classe. Se "^" è realmente necessario come membro della classe, assicurate che non sia il primo carattere, o trattenetelo con un backslash Per esempio, la classe [aeiou] corrisponde ogni vocale minuscola, mentre [^aeiou] corrisponde ogni carattere che non è vocale minuscola. Osservate come l'accento circonflesso "^" sia solo una scorciatoia per specificare quali caratteri sono ammessi dalla classe attraverso la definizione di quelli che non lo sono. Non si tratta di asserzione: la classe occupa solo un carattere della stringa, ma fallisce se il punto corrente di corrispondenza si trova alla fine della stringa. Quando è attiva la modalità CASELESS (default di Hamster), tutte le lettere in una classe rappresentano sia la loro versione maiuscola che quella minuscola, così, per esempio, una classe caseless [aeiou] corrisponde "A" al pari di "a", mentre una classe caseless [^aeiou] non corrisponde "A" (in questo ultimo caso anche con la modalità caseful). Il carattere di nuova riga non è mai trattato in modo speciale in classi di carattere, qualunque modalità venga adottata, sia essa PCRE_DOTALL o PCRE_MULTILINE. Una classe come [^a] corrisponderà sempre a una nuova riga. Il carattere "-" può essere usato per specificare un range di caratteri in una classe. Per esempio, [d-m] corrisponde ogni lettera tra d e m, incluse. Se un carattere "-" è richiesto come membro di una classe, deve essere trattenuto all'inizio o alla fine della classe. Non è possibile avere il carattere "]" come carattere finale di un range, dato che una sequenza come [w-] viene interpretata come classe di due caratteri. La rappresentazione ottale o esadecimale di "]" può, tuttavia, essere usata per terminare un range. I range operano in sequenza e nell'ordine ASCII. Possono anche essere usati per caratteri specificati numericamente, per esempio [\000-\037]. Se un range che include lettere viene usato quando è impostata la modalità caseless, esso corrisponde le lettere in una sorta di ordine continuo. Per esempio, [W-c] equivale a [][\^_`wxyzabc], anch'essa in modalità caseless, e se la tabella locale dei caratteri "it" è in uso, [\xc8-\xcb] corrisponde alle "e" accentante in entrambi i casi. Le sequenze \d, \D, \s, \S, \w e \W possono anche apparire all'interno di una classe di caratteri, e aggiungere i caratteri che essi corrispondono alla classe. Per esempio, [\dABCDEF] corrisponde ogni cifra esadecimale. Un accento circonflesso può essere impiegato con profitto con la versione maiuscola di queste sequenze per specificare un più ristretto set di caratteri rispetto a quello corrisposto dalla versione minuscola. Per esempio, la classe [^\W_] corrisponde ogni lettera o cifra, ma non il carattere di sottolineatura "_" (underscore). Tutti i caratteri non alfanumerici all'infuori di \, -, ^ (all'inizio) e il finale ] non sono caratteri speciali nelle classi di carattere, ma non causano alcun problema se sono trattenuti con il backslash. 1.7 Meta-carattere "|". Le alternative. Le barre verticali sono impiegate per separare modelli alternativi, all'interno dello stesso modello. Per esempio, il modello gilbert|sullivan corrisponde sia "gilbert" che "sullivan". Ogni tipo di alternativa può apparire, compresa l'alternativa vuota (corrispondenza di una stringa vuota). Il processo di verifica cerca ogni alternativa in gioco, da sinistra a destra, e applica la prima che trova riscontro. Se le alternative sono dentro un subpattern (definito più sotto), riscontrare comporta corrispondere il resto del modello principale così come le alternative presenti nel subpattern. 1.8 Modalità interne al PCRE (internal option setting). Le modalità PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL e PCRE_EXTENDED possono essere modificate dall'interno del modello attraverso una sequenza di lettere esclusive del PCRE racchiuse tra "(?" e ")". Le lettere in oggetto sono: m per PCRE_MULTILINE s per PCRE_DOTALL x per PCRE_EXTENDED Per esempio, (?im) assegna le modalità caseless e multiline. E' anche possibile offrire il loro complemento precedendo la lettera con un carattere "-" oppure, offrire una combinazione di queste modalità attivandone ora la loro funzione originale, ora il loro complemento, come in (?im-sx), che imposta PCRE_CASELESS and PCRE_MULTILINE mentre annulla PCRE_DOTALL e PCRE_EXTENDED. Se una lettera appare sia prima che dopo il carattere "-", la modalità viene disabilitata. Lo scopo di queste opzioni di modifica si comprende quando occorre il cambiamento di modalità in una parte del modello. Per le modalità che sono al di fuori di ogni subpattern (definito più sotto), l'effetto è lo stesso se la modalità viene attivata (o disattivata) all'inizio del modello principale. I modelli successivi si comportano esattamente tutti allo stesso modo: (?i)abc a(?i)bc ab(?i)c abc(?i) Tutti equivalgono a compilare il modello abc con la modalità PCRE_CASELESS attiva. In altre parole, i cambiamenti ad alto livello delle modalità si applicano all'intero modello (a meno che non ci siano altri cambiamenti all'interno delle subpattern). Se ci sono più cambiamenti di modalità a livello di pattern principale, sarà impiegato quello più a destra. Se serve un'opzione di modifica all'interno di un subpattern, l'effetto è differente. Questo è un cambiamento di modalità in in Perl 5.005. Un opzione cambia all'interno di un subpattern e influenza solo quella parte di subpattern che la segue, così: (a(?i)b)c corrisponderà abc e aBc, ma non altre stringhe (assumendo che non sia usata la modalità PCRE_CASELESS). Da questo si desume che le opzioni possono causare differenti cambiamenti di modalità in differenti parti del modello. Ogni cambiamento fatto in una alternativa viene applicato al ramo successivo all'interno dello stesso subpattern. Per esempio: (a(?i)b|c) corrisponde "ab", "aB", "c" e "C", anche se nel riscontro di "C" il cambiamento di modalità è avvenuto nel primo ramo. Questo accade perché l'effetto della modifica di un'opzione avviene a livello di compilazione. Altrimenti, si verificherebbero alcuni comportamenti piuttosto bizzarri. Una particolarità su X. La modalità (?X) è speciale perché deve sempre anticipare nel modello tutte le caratteristiche addizionali che dovrebbe influenzare, anche quando si trova al livello di pattern principale. E' quindi consigliabile collocarla all'inizio. 1.9 I sotto modelli (subpattern). I subpattern sono delimitati da parentesi (tonde), e possono essere nidificati. Inserire parte di un modello come subpattern ha due effetti: 1. Localizza un set di alternative. Per esempio, il modello: cat(aract|erpillar|) corrisponde a una delle parole "cat", "cataract" oppure "caterpillar". Senza le parentesi, corrisponderebbe "cataract", "erpillar" oppure una stringa vuota. 2. Pianifica il subpattern come subpattern di cattura (come definito sopra). When the whole pattern matches, that portion of the subject string that matched the subpattern is passed back to the caller via the ovector argument of pcre_exec(). xxx Le parentesi aperte sono contate da sinitra a destra (partendo da 1) per ottenere il numero delle subpattern di cattura. Per esempio, se la stringa "the red king" viene affrontata dal modello: the ((red|white) (king|queen)) le substringhe catturate sono "red king", "red", and "king" e sono numerate 1, 2, and 3. Il fatto che le parentesi realizzino due funzioni non è sempre di aiuto. In alcuni casi il raggruppamento dei subpattern è richiesto senza la caratteristica della cattura. se una parentesi aperta è seguita da "?:", il subpattern non sarà definito "di cattura", e non ne sarà tenuto conto nel computo del numero delle subpattern di cattura successive. Per esempio, se la stringa "the white queen" è affrontata dal modello: the ((?:red|white) (king|queen)) le substringhe catturate sono "white queen" e "queen" e sono numerate 1 e 2. The maximum number of captured substrings is 99, and the maximum number of all subpatterns, required at the start of a non-capturing subpattern, the option letters may appear between the "?" and the ":".xxx Così i due modelli: (?i:saturday|sunday) (?:(?i)saturday|sunday) corrispondono esattamente lo stesso set di stringhe. Poiché i rami alternativi sono testati da sinistra verso destra e le opzioni di modalità non sono reimpostate prima della fine del subpattern, il cambiamento di modalità in un ramo influenzerà i rami subseguenti. In tal modo il modello sopra corrisponderà "SUNDAY" così come "Saturday". 1.10 Le ripetizioni La ripetizione è specificata da quantificatori, i quali possono seguire ognuno dei seguenti articoli: un carattere singolo, possibilmente il metacarattere una classe di caratteri una back reference (trattate al punto successivo) un subpattern tra parentesi (a meno che non sia un'asserzione, illustrate più avanti) Il quantificatore specifica un minimo e un massimo numero di corrispondenze permesse, assegnando i due valori in parentesi graffe, separate da una virgola. Questi valori devono essere inferiori a 65536, e il primo deve essere inferiore o uguale al secondo. Per esempio: z{2,4} corrisponde "zz", "zzz", or "zzzz". Una parentesi graffa di chiusura per conto suo non rappresenta un carattere speciale. Se il secondo valore viene omesso, ma la virgola è presente, non c'è alcun limite superiore; se il secondo valore e la virgola sono entrambi omessi, il quantificatore specifica un numero esatto di corrispondenze richieste. Così: [aeiou]{3,} corrisponde almeno 3 successive vocali, ma può corrisponderne molte di più, mentre \d{8} corrisponde esattamente 8 cifre. Una parentesi graffa aperta che appare in una posizione dove un quantificatore non è permesso, o uno che non corrisponde la sintassi di un quantificatore, è considerato come carattere letterale. Per esempio, {,6} non è un quantificatore, ma una stringa letterale di quattro caratteri. Il quantificatore {0} è permesso e determina una reazione dell'espressione come se il precedente articolo e il quantificatore non fossero presenti. Per convenienza, (e compatibilità all'indietro) i tre più comuni quantificatori hanno specifiche abbreviazioni: * equivale a {0,} + equivale a {1,} ? equivale a {0,1} E' possibile costruire cicli infiniti seguendo un subpattern che non corrisponde alcun carattere con un quantificatore che non prevede limiti superiori, per esempio: (a?)* Le versioni più recenti di Perl e PCRE forniscono un errore all'atto della compilazione per alcuni modelli. Tuttavia, poiché ci sono casi dove questa possibilità potrebbe rivelarsi utile, tali modelli sono già stati accolti, ma se qualsiasi ripetizione del subpattern non dovesse corrispondere ad alcun carattere, il ciclo si spezzerebbe per forza. I quantificatori sono avidi di risorse per eccellenza, in altre parole, essi corrispondono il più possibile (fino al massimo numero di volte possibili), senza causare l'arresto del modello per fallimento. L'esempio classico di dove questo crea problemi è nel tentativo di corrispondere commenti nel sorgente C. Questi appaiono tra le sequenze /* e */ e dentro una singola sequenza possono comparire i caratteri * e /. Un tentativo di corrispondere i commenti in C si ha comparando il modello: /\*.*\*/ con la stringa /* first command */ not comment /* second comment */ ma fallirà poiché corrisponde l'intera stringa a causa dell'avidità dell'elemento .* . Tuttavia, se un quantificatore è seguito da un punto interrogativo, allora cesserà di essere avido e invece corrisponderà il minimo numero di volte possibili, così il modello: /\*.*?\*/ farà la cosa giusta con un commento C. Il significato dei vari quantificatori non è cambiato, ma solo il numero preferibile di corrispondenze. Non confondete questo uso delle doppie, come in: \d??\d che di preferenza corrisponde una sola cifra, ma può anche corrisponderne due se quello è l'unico modo perché il resto del modello corrisponda. which matches one digit by preference, but can match two if that is the only way the rest of the pattern matches.xxx Se si attivasse la modalità PCRE_UNGREEDY (comunque non disponibile su Perl) allora i quantificatori non sarebbero avidi per definizione, ma individualmente uno potrebbe essere reso avido facendolo seguire da un punto interrogativo. In altre parole, esso inverte la condotta predefinita. Quando un subpattern viene quantificata con un valore minimo più grande di 1 o con un limitato valore massimo, sarà richiesto tanto più spazio per il modello compilato in proporzione alla dimensione dei valori minimi e massimi. Se un modello parte .* con allora sarà implicitamente ancorato, dato che qualsiasi cosa segua sarà processata su ogni posizione della stringa. PCRE tratta questa stringa come se fosse preceduta da \A. Quando una subpattern di cattura è ripetuta, il valore catturato è la sottostringa che corrisponde la ripetizione finale. Per esempio, dopo: (tweedle[dume]{3}\s*)+ con la stringa "tweedledum tweedledee" il valore della substringa catturata sarà "tweedledee". Tuttavia, se ci fossero subpattern nidificate, il valore corrispondente catturato potrebbe essere impostato. Per esempio, dopo: /(a|(b))+/ con la stringa "aba" il valore della seconda substringa catturata è "b". 1.11 Back Reference Al di fuori di una classe di caratteri, un backslash seguito da una cifra più grande di 0 (anche molto più grande) è una back reference che serve a catturare subpattern vicine (ovvero alla sua sinistra) nel modello, a condizione che ci siano sufficienti (...) parentesi di cattura precedenti. Tuttavia, se il numero decimale che segue il backslash è inferiore a 10, è sempre considerato come back reference, e causa un errore solo se non ci sono altrettante parentesi di cattura alla sua sinistra, per un numero pari quindi a quello riportato dopo il backslash inferiore a 10. Leggete il punto riservato al backslash più sopra per avere ulteriori dettagli sul trattamento delle cifre seguite da un backslash. Una back reference corrisponde qualsiasi cosa corrisposta dal subpattern di cattura nella stringa corrente, piuttosto che qualsiasi cosa che corrisponde lo stesso subpattern. Così il modello (sens|respons)e and \1ibility corrisponde "sense and sensibility" e "response and responsibility", ma non "sense and responsibility". Se è attiva la modalità caseful durante il funzionamento della back reference, allora la "dimensione" della lettera diviene rilevante. Per esempio, ((?i)rah)\s+\1 corrisponde "rah rah" e "RAH RAH", ma non "RAH rah", anche se il subpattern originale di cattura viene corrisposto in modalità caseless. Ci può essere più di una back reference verso lo stesso subpattern. Se un subpattern non è stato ancora usato in una particolare corrispondenza, allora ogni back reference verso di esso fallirà comunque. Per esempio, il modello (a|(bc))\2 fallisce sempre se parte per corrispondere "a" piuttosto di "bc". Poiché ci può essere un massimo di 99 back reference, tutte le cifre che seguono il backslash sono considerate come potenziali numeri per back reference. Se il modello continua proprio con un carattere cifra, allora si deve usare un delimitatore per terminare la back reference. Se è attiva la modalità PCRE_EXTENDED questo può essere costituito da uno spazio bianco. Altrimenti, si può usare anche un commento vuoto. Una back reference che si trova dentro le parentesi alle quali si riferisce fallisce quando il subpatter è usato per la prima volta, così, per esempio, (a\1) non corrisponderà mai. Tuttavia, tali reference possono essere utili all'interno di subpattern ripetute. Per esempio il modello (a|b\1)+ corrisponde ogni numero di "a" e anche "aba", "ababaa", ecc. A ogni ripetizione del subpattern, la back reference corrisponde la stringa di caratteri corrispondente alla precedente ripetizione. Perché questa funzioni, il modello deve essere tale da non imporre alla prima ripetizione di aver bisogno di corrispondere la back reference. Questo può essere realizzato usando l'avvicendamento, come nell'esempio precedente o usando un quantificatore con un minimo pari a zero. 1.12 Le asserzioni Un'asserzione è un test sui caratteri seguenti o precedenti il punto di corrispondenza corrente senza in realtà misurare alcun carattere. Le semplici asserzioni codificate come \b, \B, \A, \Z, \z, ^ e $ sono state descritte nei punti precedenti. Le asserzioni più complesse sono codificate come subpattern. Ce ne sono di due tipi: quelle che guardano avanti (lookahead) rispetto alla posizione corrente nella stringa, e quelle che guardano indietro (look behind). Un asserzione subpattern è normalmente corrisposta, ad eccezione di quando non richiede di cambiare il punto di corrispondenza corrente. Le asserzioni (lookahead) cominciano con (?= per quelle positive e con (?! per quelle negative. Per esempio, \w+(?=;) corrisponde una parola seguita da un punto e virgola, ma non comprende il punto e virgola nella corrispondenza, e foo(?!bar) corrisponde ogni ricorrenza di "foo" non seguita da "bar". Osservate questo modello apparentemente simile: (?!foo)bar non trova la ricorrenza di "bar" preceduta da qualcosa di diverso da "foo"; trova qualsiasi ricorrenza di "bar", non importa quale, poiché l'asserzione (?!foo) è sempre vera quando i tre caratteri vicini sono "bar". Un'asserzione lookbehind deve realizzare questo scopo. Le asserzioni lookbehind cominciano con (?<= per quelle positive e con (? come in questo esempio: (?>\d+)bar Questo tipo di parentesi imprigiona la parte del modello che contiene una volta che ha trovato una ricorrenza, mentre un ulteriore fallimento nel modello non è in grado di desistere su se stesso. Una descrizione alternativa è che un subpattern di questo tipo corrisponde la stringa di caratteri che un identico modello, per conto suo, corrisponderebbe, se ancorato al punto corrente nella stringa. I subpattern "once-only" non sono subpattern di cattura. Once-only subpatterns are not capturing subpatterns. Semplici casi quali l'esempio sopra possono essere pensati come una replica che deve inghiottire qualsiasi cosa. Così, mentre sia \d+ che \d+? sono preparate per adeguare il numero di cifre che corrispondono al fine di far trovare una ricorrenza al resto del modello, (?>\d+) può solo corrispondere un'intera senquenza di cifre. Questa costruzione può sicuramente contenere arbitrariamente subpattern complicate, e può essere nidificata. 1.14 Subpattern condizionati E' possibile costringere il processo di corrispondenza a ubbidire a un subpatter in modo condizionato ovvero a scegliere tra due alternative di subpattern, dipendendo dal risultato di un'asserzione, sia nel caso in cui un precedente subpattern di cattura corrisponda, sia nel caso opposto. Le due possibili forme di subpattern condizionati sono: (?(condition)yes-pattern) (?(condition)yes-pattern|no-pattern) Se la condizione viene soddisfatta, viene usato lo "yes-pattern"; altrimenti il "no-pattern" (se presente). Se ci sono più di due alternative nel subpattern, si verificherà un errore di compilazione. Ci sono due tipi di condizione. Se il testo tra le parentesi consiste in una sequenza di cifre, allora la condizione è soddisfatta se il subpattern di cattura di quel numero è stato precedentemente corrisposto. Considerate il seguente modello, il quale contiene spazi bianchi non significativi per renderlo più leggibile (si assume la modalità PCRE_EXTENDED) e per dividerlo in tre parti per semplicità di analisi: ( \( )? [^()]+ (?(1) \) ) La prima parte corrisponde un'apertura di parentesi facoltativa, e se quel carattere è presente, imposta essa come la prima substringa di cattura. La seconda parte corrisponde uno o più caratteri che non sono tra parentesi. La terza parte è una subpattern condizionata che processa se il primo set di parentesi corrisponda o meno. Se corrispondono, ovvero, se la stringa comincia con un'apertura di parentesi, la condizione è vera, e così viene applicato lo yes-pattern, mentre una parentesi di chiusura viene richiesta. Altrimenti, dato che non è presente il no-pattern, il subpattern non troverà alcuna ricorrenza. In altri termini, questo modello corrisponde una sequenza di non-parentesi, occasionalmente racchiuse nelle parentesi. Se la condizione non è una sequenza di cifre, deve essere un'asserzione. Questa può essere un'asserzione positiva o negativa, lookahead o lookbehind. Considerate questo modello, nuovamente contenente spazi bianchi non significativi, e con le due alternative nella seconda riga. (?(?=[^a-z]*[a-z]) \d{2}[a-z]{3}-\d{2} | \d{2}-\d{2}-\d{2} ) La condizione è un'asserzione positiva lookahead che corrisponde una sequenza opzionale di non-lettere seguite da una lettera. In altri termini, processa la presenza di almeno una lettera nella stringa. Se viene trovata una lettera, la stringa viene corrisposta contro la prima laternativa; altrimenti viene corrisposta contro la seconda. Questo modello corrisponde le stringhe in una di queste due forme dd-aaa-dd oppure dd-dd-dd, dove aaa sono lettere e dd sono cifre. 1.15 Commenti La sequenza (?# segna l'inizio di un commento che continua fino a la parentesi di chiusura successiva. Parentesi nidificate non sono permesse. I caratteri che costituiscono un commento non hanno alcun ruolo attivo nel funzionamento del modello. Se è attiva la modalità PCRE_EXTENDED, un carattere # non trattenuto al di fuori di una classe di caratteri introduce un commento che continuerà fino al carattere di nuova riga nel modello. Alcune voci che possono apparire nei modelli sono più efficienti di altre. E' più efficiente usare un carattere di classe come [aeiou] che un set di alternative quali (a|e|i|o|u). In genere, per la più semplice costruzione che provvede a una determinata condotta, è anche la più efficiente. Il libro di Jeffrey Friedl contiene molte discussioni sull'ottimizzazione delle espressioni regolari per la performance migliore. 1.16 Credits Questa sezione costituisce semplicemente una traduzione in lingua italiana delle note sul PCRE - Perl compatible regular expressions - che si possono trovare in allegato alle ultime versioni di Xnews. La traduzione è realizzata, al meglio delle conoscenze dell'autore di questa guida, e ne rappresenta quindi anche un tentativo di interpretazione. Le routine per le "regular expression" impiegate in Hamster sono basate, come già anticipato altrove, sulle porte Win32 del package "Perl-Compatible Regular Expression (PCRE)" scritto da: Philip Hazel University Computing Service, New Museums Site, Cambridge CB2 3QG, England. Phone: +44 1223 334714 Copyright (c) 1998 University of Cambridge. Sezione 2: Espressioni regolari - Perl Regular Expression Tutorial ------------------------------------------------------------------ 2.1 Introduzione al tutorial PCRE Un'espressione regolare è una stringa di caratteri che deve dire al ricercatore quale stringa (o stringhe) state cercando. Di seguito sarà spiegato il formato di un'espressione regolare in dettaglio. Se avete familiarità con il Perl, conoscete già la sintassi. Se avete familiarità con Unix, dovreste conoscere che ci sono sottili differenze tra le espressioni regolari in Perl e quelle in Unix. 2.2 Semplici esempi di espressioni regolari Nella sua forma più semplice un'espressione regolare è costituita esattamente da una parola o una frase da cercare. Per esempio: gauss dovrebbe corrispondere ogni stringa con la parola "gauss" dentro di essa. In questo modo, le stringhe con "gauss", "gaussian" oppure "degauss" saranno corrisposte tanto quanto quelle che contengono le frasi "de-gauss the monitor" oppure "gaussian elimination." Altri esempi sono: carbon corrisponderà tutte le stringhe con "carbon" o che menzionano carbon al loro interno (carbonization, hydrocarbons oppure carbon-based life forms). hydro corrisponderà tutte le stringhe con "hydro" all'interno di esse. Quindi, vanno bene "hydro", "hydrogen" oppure "hydrodynamics" tanto quanto "hydroplane" oppure "hydroelectric", anche se costituissero una sola parola in un intero contesto. oxy corrisponderà tutte le stringhe con "oxy" all'interno di esse. Questo potrebbe essere usato per trovare una stringa che parla di oxygen, boxy houses oppure oxymorons. top ten Osservate che gli spazi potrebbero costituire parte dell'espressione regolare. L'espressione di cui sopra potrebbe essere usata per trovare "top ten lists", ma anche "stop tension". 2.3 Metacaratteri Alcuni caratteri hanno un significato speciale per il ricercatore. Questi caratteri sono chiamati metacaratteri. Benché possano sembrare confusi in apparenza, essi aggiungono un bel po' di flessibilità e utilità al ricercatore. Il punto (.) è comunemente usato come metacarattere. Esso corrisponde esattamente un carattere, qualunque esso sia. Per esempio, l'espressione regolare: 2,.-Dimethylbutane corrisponderà "2,2-Dimethylbutane" e "2,3-Dimethylbutane". Osservate come il punto misuri esattamente un carattere. Non corrisponde a una stringa di caratteri, né a una stringa vuota (null). Così "2,200-Dimethylbutane" e "2,-Dimenthylbutane" non saranno corrisposte dalle espressioni regolari suindicate. Ma come si fa se volete cercare una stringa contenente un punto? Per esempio, supponete di voler cercare riferendovi ai paragrafi. La seguente espressione regolare potrà funzionare, 3.14 <---sbagliato ma, oltre a corrispondere "3.14", troverà anche "3514", "3f14" oppure persino "3+14". In breve, ogni stringa che rispetti, anche solo in parte, la forma "3x14", dove x è ogni possibile carattere, sarà corrisposta dall'espressione regolare suindicata. Per superare questo empasse, introduciamo un secondo metacarattere, il backslash "\". Il backslash può essere usato per indicare che il carattere immediatamente alla sua destra deve essere considerato in modo letterale. Così, per cercare la stringa "3.14", noi dovremo usare: 3\.14 <---giusto Questo viene chiamato "quoting" (citazione, l'azione del citare). Noi dovremmo dire che il punto nell'espressione regolare di cui sopra è stato citato (quoted, ma anche "quotato" nel gergo telematico della Usenet italiana). In generale, ogniqualvolta il backslash è collocato prima di un metacarattere, il ricercatore tratta il metacarattere letteralmente piuttosto di invocare il suo speciale significato. Sfortunatamente, il backslash è usato per altre cose oltre a quotare metacaratteri. Molti caratteri "normali" godono di un significato particolare quando sono preceduti da un backslash. La regola empirica è che, se si quota un metacarattere questo ritorna al suo significato normale e letterali, mentre se si quota un carattere normale, questo, associato a \ potrebbe trasformarsi in un metacarattere. Diamo un'occhiata ai più comuni metacaratteri. Consideriamo prima il punto interrogativo. Il punto interrogativo indica che il carattere immediatamente precedente ad esso deve essere considerato 0 volte o 1 volta. Così: m?ethane corrisponderà sia "ethane" che "methane". In modo analogo, comm?a corrisponderà sia "coma" che "comma". Un altro metacarattere è l'asterisco (*). Questo indica che i caratteri immediatamente alla sua sinistra possono essere ripetuti più volte, incluso lo zero. Così: ab*c corrisponderà "ac", "abc", "abbc", "abbbc", "abbbbbbbbc" e ogni stringa che comincia con "a", se seguita da una sequenza di "b" e terminante con "c". Il metacarattere "+" indica che il carattere immediatamente precedente può essere ripetuto una o più volte. Funziona esattamente come "*", ad eccezione della corrispondenza delle stringhe nulle. Così: ab+c non potrà corrispondere "ac", ma "abck, "abbc", "abbbc", "abbbbbbbbc" e così via. I metacaratteri possono essere combinati. Una combinazione comune include il punto immediatamente seguito dall'asterisco. Questo viene usato per corrispondere una stringa arbitraria di ogni possibile lunghezza, compresa quella nulla. Per esempio: cyclo.*ane corrisponderà "cyclodecane", "cyclohexane" e persino "cyclones drive me insane." Ogni stringa che comincia con "cyclo", seguita da una stringa arbitraria e terminante con "ane" verrà corrisposta. Osservate che la stringa "null" sarà corrisposta con la coppia ".*"; così, "cycloane" viene compreso nel campo delle ricorrenze possibili. Se volete cercare per articoli che parlano di "cyclodecane" e "cyclohexane", ma non siete interessati a quelli "cyclones drive me insane", potreste affiancare tre punti come segue: cyclo...ane Questo corrisponderà "cyclodecane" e "cyclohexane", ma non "cyclones drive me insane". In breve saranno corrisposte tutte le stringhe lunghe undici caratteri che cominciano per "cyclo" e terminano per "ane". ("cyclopentane" non sarà corrisposta perché lunga dodici caratteri e non undici). Qui ci sono alcuni esempi che concernano il backslash. Osservate l'importanza della posizione del backslash. a\.*z Corrisponde ogni stringa che comincia con "a", seguita da una serie di punti (oppure nessuno, ovvero serie a lunghezza zero) e terminano per "z". Così "az", "a.z", "a..z", "a...z"e così via sono tutti corrisposti. a.\*z (Osservate: il backslash e il punto sono stati invertiti in questa espressione regolare) Corrisponde ogni stringa che comincia con una "a", seguita da un carattere arbitrario e terminante con "*z". Così, "ag*z", "a5*z" e "a@*z" sono tutte corrisposte. Solo le stringhe lunghe quattro caratteri, dove il primo carattere è "a", il terzo "*", il quarto "z", sono corrisposte. a\++z Corrisponde ogni stringa che comincia con "a", seguita da una serie di caratteri "+" e terminante in "z". Ci deve essere almeno un "+" tra la "a" e la "z". Così, "az" non è corrisposto, ma "a+z", "a++z", "a+++z", etc. lo saranno. a\+\+z Corrisponde solo la stringa "a++z". a+\+z Corrisponde ogni stringa che comincia con una serie di "a", seguita da un singolo "+" e terminante con "z". Ci deve essere almeno una "a" all'inizio della stringa. Così, "a+z", "aa+z", "aaa+z" e così via saranno corrisposte, mentre "+z" no. a.?e Corrisponde "ace", "ale", "axe" e ogni altra stringa composta da tre caratteri cominciante con "a" e terminante in "e"; sarà corrisposto anche "ae". a\.?e Corrisponde "ae" e "a.e". Nient'altro. a.\?e Corrisponde ogni stringa di lunghezza pari a quattro caratteri cominciante con "a" e terminante con "?e". Così, "ad?e", "a1?e" e "a%?e" saranno corrisposte. a\.\?e Corrisponde solo a "a.?e" e nient'altro. Recentemente si è scritto che il backslash può trasformare caratteri ordinari in metacaratteri, e viceversa. Uno di questi caratteri è il metacarattere per riconoscere le cifre, invocabile con un backslash seguito da una "d" (minuscola sempre), come questo: "\d". La "d" deve essere minuscola per le ragioni spiegate più oltre. Tale metacarattere corrisponde esattamente una cifra, ovvero "0", "1", "2", "3", "4", "5", "6", "7", "8" or "9". Per esempio, l'espressione regolare: 2,\d-Dimethylbutane corrisponde "2,2-Dimethylbutane", "2,3-Dimethylbutane" e così via. Allo stesso modo: 1\.\d\d\d\d\d corrisponde ogni numero frazionato da 1.00000 a 1.99999 compresi. Potremmo combinare \d con altri metacaratteri, per esempio: a\d+z corrisponde ogni stringa che comincia per a, seguita da una serie di numeri e terminante in "z". (Osservate che è usato il segno "+" e quindi "az" non corrisponde.) La lettera "d" nella stringa "\d" deve essere minuscola. Questo poiché c'è un altro metacarattere, complemento del precedente, che si indica con la maiuscola "D" e sarebbe "\D". "\D" identifica tutto ciò che non è una cifra, così: a\Dz corrisponde "abz", "aTz" or "a%z", ma non "a2z", "a5z" oppure "a9z". Similmente, \D+ corrisponde ogni stringa non nulla che non contiene caratteri numerici. Osservate che invertendo da minuscola a maiuscola e viceversa, invertiamo anche il senso stesso della sequenza metacarattere. Questo vale anche per altri metacaratteri che operano insieme alla backslash. Ci sono tre altre sequenze metacaratteri formato abbinato al backslash. Il primo è il metacarattere "word", che corrisponde esattamente una lettera, un numero o il segno di sottolineatura "_" (underscore). Si scrive "\w". Il suo complemento è "\W", che corrisponde ogni singolo carattere ad eccezione di lettere, numeri e "_" (underscore). Così: a\wz corrisponde "abz", "aTz", "a5z", "a_z", oppure ogni altra stringa di tre caratteri che comincia con "a" e finisce per "z", il cui secondo carattere sia una lettera (maiuscola o minuscola), un numero oppure "_". Allo stesso modo, a\Wz non corrisponde "abz", "aTz", "a5z" oppure "a_z". Corrisponde "a%z", "a{z", "a?z" oppure ogni stringa di tre caratteri che comincia con "a" e finisce per "z", il cui secondo carattere non sia una lettera, un numero oppure "_". (Questo significa che il secondo carattere deve essere un simbolo o uno spazio vuoto.) Il metacarattere spazio vuoto "\s" corrisponde esattamente un carattere vuoto (whitespace). E' definito come spazio, tabulazione, nuovariga oppure ogni carattere che non usa inchiostro nel processo di stampa.) Il suo complemento, che corrisponde ogni carattere visibile (printing a video, per esempio), è "\S". Così: a\sz corrisponderà ogni stringa di tre caratteri che comincia con "a" e terminante in "z", il cui secondo carattere è uno spazio, tabulazione o nuova riga. Allo stesso modo, a\Sz corrisponde ogni stringa di tre caratteri che comincia con "a" e finisce con "z" il cui secondo carattere non è uno spazio, tabulazione o nuova riga. (così, il secondo carattere potrebbe essere una lettera, numero o simbolo). Il metacarattere "confine di parola" "\b" corrisponde i confini delle parole; cioè corrisponde spazi bianchi, punteggiatura e inizio e fine del testo. Il suo complemento è "\B". Così: \bcomput corrisponderà "computer" oppure "computing", ma non "supercomputer" dato che non c'è nessuno spazio o punteggiatura tra "super" e "computer". Allo stesso modo: \Bcomput non corrisponderà "computer" oppure "computing", a meno di non far parte di una parola pià grande quale "supercomputer" oppure "recomputing". Osservate che "_" viene considerato un carattere "word". Così: super\bcomputer non corrisponderà "super_computer". C'è un ulteriore sequenza di metacaratteri che inizia con lo backslash, il metacarattere ottale. Il metacarattere ottale appare in questa forma: "\nnn", dove "n" è un numero da zero a sette. Questo è usato per specificare caratteri appartenenti al set che non hanno tipi equivalenti. Per esempio: \007 corrisponderà tutte le stringhe con incluso un carattere ASCII "bell" campanello. (bell è individuato dal valore ASCII pari a 7). E' raro aver bisogno di ricorrere ai metacaratteri ottali. Ci sono altri tre metacaratteri che possono essere usati. Il primo è la parentesi graffa. Questo metacarattere segue un carattere normale e contiene due numeri separati da una virgola e ovviamente attorniati dalle parentesi "{n,m}". Funziona come il metacarattere asterisco, ad eccezione che la lunghezza della stringa questa volta deve essere compresa tra un minimo e un massimo specificato dai due numeri in parentesi. Così: ab{3,5}c corrisponderà "abbbc", "abbbbc" oppure "abbbbbc". Nient'altro. Allo stesso modo: .{3,5}pentane corrisponderà "cyclopentane", "isopentane" oppure "neopentane" ma non "n-pentane", dato che "n-" è lungo solo due caratteri. Il metacarattere "alternativa" è rappresentato da una barra verticale "|". Indica una biforcazione separata da due o più scelte possibili. Per esempio: isopentane|cyclopentane corrisponderà ogni stringa contenente "isopentane" oppure "cyclopentane" o entrambi. Tuttavia, non corrisponderà "pentane", "n-pentane" oppure "neopentane." L'ultimo metacarattere è rappresentato dalla parentesi quadra. Le parentesi quadre (classi di carattere) corrispondono un solo carattere se fa parte dell'intervallo o degli intervalli (range) all'interno delle parentesi([]). Per esempio: \s[cmt]an\s corrisponderà "can", "man" e "tan", ma non "ban", "fan" oppure "pan". Allo stesso modo, 2,[23]-dimethylbutane corrisponderà "2,2-dimethylbutane" oppure "2,3-dimethylbutane", ma non "2,4-dimethylbutane", "2,23-dimethylbutane" oppure "2,-dimethybutane". I range di caratteri possono essere inseriti usando il trattino (-) in mezzo alle parentesi. Per esempio: a[a-d]z corrisponderà "aaz", "abz", "acz" oppure "adz", e nient'altro. Allo stesso modo: textfile0[3-5] corrisponderà "textfile03", "textfile04", oppure "textfile05" e nient'altro. Se volete includere un trattino (-) all'interno delle parentesi con il suo significato letterale, invece di denotare un range, inseritelo immediatamente prima della parentesi quadra di destra. Così: a[1234-]z e a[1-4-]z faranno entrambi la stessa cosa. Corrispondono "a1z", "a2z", "a3z", "a4z" oppure "a-z" e nient'altro. Le parentesi quadre possono anche inserire il complemento dell'intervallo (inversione) con la presenza di un accento circonflesso (^) immediatamente dopo la parentesi di sinistra. Così: textfile0[^02468] corrisponderà ogni stringa di dieci caratteri che comincia con "textfile0" e terminante con qualsiasi cosa ad eccezione di un numero pari. Le inversioni e i range possono essere combinati, quindi: \W[^f-h]ood\W corrisponde ogni stringa alfanumerica di quattro lettere terminante in "ood" ad eccezione di "food", "good" oppure "hood". (Così "mood" e "wood" saranno entrambi corrisposti.) Osservate che dentro le parentesi, di solito le regole di quoting non vengono applicate e gli altri metacaratteri non sono disponibili. Gli unici caratteri nelle parentesi quadre che possono essere quotati sono "[", "]" e, ovviamente, "\". Così: [\[\\\]]abc corrisponde ogni stringa di quattro lettere terminante con "abc" e che inizia con "[", "]" oppure "\". 2.4 Caratteri riservati A causa del modo di lavorare del ricercatore, i seguenti metacaratteri non dovrebbero essere usati, anche se sono considerati validi per il Perl. Essi sono: ^ (permessi all'interno delle parentesi quadre) $ (permesso all'interno delle parentesi quadre) \n \r \t \f \b ( ) (permessi all'interno delle parentesi quadre. Se desiderate ricercare delle parentesi con del testo, dovrete quotare quotarle) \1, \2 ... \9 \B : ! 2.5 Cose da ricordare Qui ci sono altre cose che dovreste conoscere circa il funzionamento delle espressioni regolari. Le espressioni regolari dovrebbero essere impiegate come ultima risorsa poiché sono complesse e, inoltre, può richiedere più lavoro organizzare una ricerca che controllare visivamente un lungo elenco di ricorrenze (a meno che non prendiate familiarità con le espressioni regolari). Il numero delle ricorrenze che possono essere mostrate è limitato a un massimo di 200. Questo per minimizzare il consumo di risorse sul vostro sistema. la ricerca è case insensitive; così mopac Mopac MOPAC appartengono allo stesso set di stringhe e ognuno di essi potrà corrispondere "mopac", "MOPAC", "Mopac", "mopaC", "MoPaC", "mOpAc" e così via. In questo modo non dovrete preoccuparvi dell'uso delle maiuscole. (Osservate che, tuttavia, i metacaratteri devono avere la propria lettera. Questo è specialmente importante per i metacaratteri che hanno un rispettivo complemento. Al di fuori delle parentesi quadrate, dovete quotare le parentesi tonde, graffe o quadrate per assumere il loro significato letterale.