Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Espressioni regolari Introduzione per esempi
Luca “Syslac” Mezzalira Montebelluna Linux User Group
19 gennaio 2011 – Montebelluna
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Licenza d’utilizzo c 2010, Luca “Syslac” Mezzalira. Copyright Questo documento viene rilasciato secondo i termini della licenza Creative Commons (http://creativecommons.org). L’utente è libero di: distribuire, comunicare al pubblico, rappresentare o esporre in pubblico la presente opera alle seguenti condizioni: Attribuzione Deve riconoscere la paternità dell’opera all’autore originario. Non commerciale Non può utilizzare quest’opera per scopi commerciali. Share-Alike Puoi distribuire eventuali modifiche a quest’opera solo con licenza identica o equivalente a questa. In occasione di ogni atto di riutilizzazione o distribuzione, deve chiarire agli altri i termini della licenza di quest’opera. Se ottiene il permesso dal titolare del diritto d’autore, è possibile rinunciare a ciascuna di queste condizioni. Le utilizzazioni libere e gli altri diritti non sono in nessun modo limitati da quanto sopra. Questo è un riassunto in lingua corrente dei concetti chiave della licenza completa (codice legale), reperibile sul sito Internet http://creativecommons.org/licenses/by-nc-sa/3.0/legalcode RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Sommario 1
Introduzione Presentazioni Pronti, via
2
Matching Ricerca di testo Chi si iscrive al mio sito? Non fidarsi è meglio
3
Captures Una feature utile Configurazioni Greedy matching
4
Sostituzione Yet another boring example Qualcosa di pratico
5
Cos’altro c’è Look around Verso l’infinito . . . . . . e oltre
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Presentazioni
Miti da sfatare Stasera vogliamo sfatare il mito che le espressioni regolari siano brutte e difficili :
/((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/
Ok, forse non è stato l’esempio più ispirato, ma abbiamo due ore. . . RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Presentazioni
Iniziamo a conoscerle Idea Un’espressione regolare non è altro che un modo formale di descrivere del testo. L’idea è quindi di usarle per controllare se un dato testo corrisponde o meno alle descrizione data mediante regexp.
Come leggerle Il trucco (se si può parlare di trucco) è leggerle a blocchi, o carattere per carattere, senza sperare che il significato globale si riveli di colpo e subito. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Presentazioni
Cosa non sono Attenzione Nonostante possano essere accoppiate con altri strumenti dati dal linguaggio di programmazione scelto, le espressioni regolari da sole non permettono di localizzare che punto del testo verifica la descrizione data. Infatti, eseguendo il matching con espressioni regolari, verrà restituito semplicemente: vero Il match riesce
RegExp Intro
falso Il match fallisce
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Pronti, via
Qualche nota tecnica Standard Dove non è specificato, faccio riferimento all’implementazione presente in Perl, fino alla versione 5.* (PCRE) Nella maggior parte dei casi, la sintassi presentata non è comunque specifica e funzionerà sia che il vostro linguaggio preferito sia Perl, Python, PHP, o chi per essi.
Eccezioni È più probabile incontrare eccezioni nelle feature avanzate, o nelle parentesi per Vim :D
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Pronti, via
Travellers beware!
Esempi Con l’eccezione di un paio, tutti gli esempi sono miei; dovrei essermi ricordato di testarli tutti, ma non escludo bug vari. Siete invitati quindi, se avete intenzione di usarli, a verificarne la correttezza (e in caso di problemi, segnalateli pure)
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Pronti, via
Troppa teoria!
Se vi sembra un’introduzione anche troppo lunga per un corso per esempi, non preoccupatevi perché. . . è ora di iniziare1
1 RegExp Intro
Ma non aspettatevi un inizio scoppiettante MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
Ho scritto “ciao”? /ciao/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
Ho scritto “ciao”? /ciao/ Ve l’avevo detto che l’inizio sarebbe stato facile
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
Ho scritto “ciao”? /ciao/
Qualunque testo compaia all’interno di una regexp, ad eccezione di alcuni caratteri che hanno significati speciali (tutti i caratteri alfanumerici, ad esempio, non ne hanno) è interpretato letteralmente. Anche i caratteri speciali possono essere interpretati letteralmente attraverso escape con backslash
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
E il mio login?
Se volessimo validare ad esempio un nome utente in maniera case-insensitive?
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
E il mio login?
Se volessimo validare ad esempio un nome utente in maniera case-insensitive? /frodo/i
Un semplice modificatore /i è tutto quello che serve
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Ricerca di testo
Continua Nota Chiaramente, funziona con qualsiasi parola ma, per stavolta con il rischio di annoiare lo ripeto, da solo non può aiutarvi a localizzare l’occorrenza.
Credo che sia un insulto insistere oltre su queste cose, quindi procediamo.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
“Controllo” email /.+@.+/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
“Controllo” email /.+@.+/ punto Carattere speciale che significa “accetta qualunque carattere”
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
“Controllo” email /.+@.+/ punto Carattere speciale che significa “accetta qualunque carattere” quantificatori Si può fare in modo che l’espressione faccia un match di più di un carattere con un quantificatore; i più comuni sono : * 0 o più volte + 1 o più volte ? 0 o 1 volta
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
“Controllo” email /.+@.+/ punto Carattere speciale che significa “accetta qualunque carattere” quantificatori Si può fare in modo che l’espressione faccia un match di più di un carattere con un quantificatore; i più comuni sono : * 0 o più volte + 1 o più volte ? 0 o 1 volta “Pronunciamola” : accettiamo come valido un testo con uno o più caratteri seguiti da un @ seguiti da uno o più caratteri. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo email /.+@[a-z]+\.[a-z\.]+/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo email /.+@[a-z]+\.[a-z\.]+/ alternative Ciò che è chiuso tra [ e ] sono alternative di caratteri da accettare in quel punto. In questo caso abbiamo usato dei range, in modo da accettare ogni lettera minuscola. nota Quindi, scrivere parole tra [] non avrà l’effetto desiderato, probabilmente.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo email /.+@[a-z]+\.[a-z\.]+/ alternative Ciò che è chiuso tra [ e ] sono alternative di caratteri da accettare in quel punto. In questo caso abbiamo usato dei range, in modo da accettare ogni lettera minuscola. nota Quindi, scrivere parole tra [] non avrà l’effetto desiderato, probabilmente. “Pronunciamola” : accettiamo come valido un testo con uno o più caratteri seguiti da un @ seguiti da lettere minuscole più un punto e altre lettere minuscole (eventualmente altri punti per domini tipo @deathstar.co.uk) RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo quasi serio email /[\w\.]+@.+\..{2,3}/ /[\w\.]+@.+\.(it|com|net)/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo quasi serio email /[\w\.]+@.+\..{2,3}/ /[\w\.]+@.+\.(it|com|net)/ character classes La \w è un esempio di classe di caratteri, viene preso qualsiasi carattere alfanumerico. alternative Se si vogliono specificare parole(gruppi di caratteri) alternative possibili, vanno separate da una |
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Controllo quasi serio email /[\w\.]+@.+\..{2,3}/ /[\w\.]+@.+\.(it|com|net)/ character classes La \w è un esempio di classe di caratteri, viene preso qualsiasi carattere alfanumerico. alternative Se si vogliono specificare parole(gruppi di caratteri) alternative possibili, vanno separate da una | “Pronunciamola” : Stavolta l’indirizzo email deve avere uno user con solo caratteri alfanumerici o punti, un segno @, e abbiamo aggiunto qualche restrizione sui domini possibili. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Intermezzo poetico /bb|[ˆb]{2}/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Intermezzo poetico /bb|[ˆb]{2}/ Negazioni Nello specificare alternative tra parentesi quadre, iniziare con ˆ è una negazione, quindi vengono considerati validi i caratteri non specificati. Ripetizioni Se si vuole un controllo più preciso di quello dato dai quantificatori generici + e *, tra { e } si può inserire il numero di volte che si vuole che compaia l’ultimo elemento.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Chi si iscrive al mio sito?
Intermezzo poetico /bb|[ˆb]{2}/ Negazioni Nello specificare alternative tra parentesi quadre, iniziare con ˆ è una negazione, quindi vengono considerati validi i caratteri non specificati. Ripetizioni Se si vuole un controllo più preciso di quello dato dai quantificatori generici + e *, tra { e } si può inserire il numero di volte che si vuole che compaia l’ultimo elemento. “Pronunciamola” : T(w)o be or not to be :Da a
RegExp Intro
Anche se onestamente sarebbe più “or to not be” MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
User-proof Vogliamo verificare che l’input dell’utente sia effettivamente nel formato corretto perché il nostro programma lo comprenda? Qualcuno sta pensando a date, valute o valori numerici con precisione fissata? Torniamo dalla nostra amica della slide introduttiva : /((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/ e vediamo se a breve riusciamo a collocarla2 :
2 RegExp Intro
Un punto bonus a chi ci riesce con solo il contesto dato finora MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
Cheat-sheet Per aiutarci, un piccolo cheat sheet delle character classes più usate. . . : \w Carattere alfanumerico \d Cifra \s Spazio \W Non alfanumerico : per tutte e tre queste classi, indicarle maiuscole significa negarle . . . e altre sequenze di escape : \n Newline \t Tab RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
Cheat-sheet - Parte 2 Alcuni simboli speciali - match che non “consumano” caratteri. ˆ Inizio stringa $ Fine stringa \b Margine di parola . . . e altri modificatori (come /i) /m Tratta come righe multiple (ˆ e $ funzionano per inizio-fine riga) /s Tratta come singola riga
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi Meglio? No?
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi Meglio? No? Allora rivediamola, insieme ad altri esempi : /((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi Meglio? No? Allora rivediamola, insieme ad altri esempi : /((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/ Controlla un numero in notazione scientifica, con parte decimale ed esponente non obbligatori.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi Meglio? No? Allora rivediamola, insieme ad altri esempi : /((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/ Controlla un numero in notazione scientifica, con parte decimale ed esponente non obbligatori. /\d+,\d{2}\W/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi Meglio? No? Allora rivediamola, insieme ad altri esempi : /((\b[0-9]+)?\.)?\b[0-9]+([eE][-+]?[0-9]+)?\b/ Controlla un numero in notazione scientifica, con parte decimale ed esponente non obbligatori. /\d+,\d{2}\W/ Controlla una valuta, con centesimi (separati da virgola) e simbolo della valuta finale obbligatori. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi - continua /\d{1,2}\D\d{1,2}\D\d{2,4}/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
I veri esempi - continua /\d{1,2}\D\d{1,2}\D\d{2,4}/ Controlla una data in formato italiano, lasciando libertà di usare come separatore (giorno-mese, etc) qualunque cosa non sia un numero, date a cifre ridotte opzionali.
Nota Per il momento non viene controllato che i due separatori coincidano, quindi anche date come 10-11/08 vengono considerate valide. Vedremo come “fare meglio”.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Non fidarsi è meglio
/x /( (\b[0-9]+)?\. #Prima della virgola )?\b [0-9]+ #Parte decimale, o tutto il numero ( [eE][-+]?[0-9]+ #* 10^??? )?\b/x /x Con questo modificatore, si possono inserire commenti e whitespace nella regexp, per rendere il tutto più leggibile.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Una feature utile
Come usarla Captures Si può “catturare” del testo in modo da poter fare riferimento a questo in parti successive dell’espressione regolare o del programma. () Di default, quello che sta tra () viene automaticamente catturato dall’espressione regolare. \1 Si può accedere alle captures in serie con \1, \2, . . . , nell’ordine in cui compaiono. non-capturing Per evitare che un raggruppamento con () catturi, basta iniziare con (?:3 3 RegExp Intro
Che non è una faccina MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Una feature utile
Mettiamole subito all’opera /\d{1,2}(\D)\d{1,2}\1\d{2,4}/
Nota tecnica In Perl, il testo catturato è disponibile anche all’esterno della regexp nelle variabili speciali $1, $2 e via di seguito. In Vim, non si può accedere a più di 9 captures. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Una feature utile
Mettiamole subito all’opera /\d{1,2}(\D)\d{1,2}\1\d{2,4}/ Assomiglia molto all’ultimo esempio, vero?
Nota tecnica In Perl, il testo catturato è disponibile anche all’esterno della regexp nelle variabili speciali $1, $2 e via di seguito. In Vim, non si può accedere a più di 9 captures. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Una feature utile
Mettiamole subito all’opera /\d{1,2}(\D)\d{1,2}\1\d{2,4}/ Assomiglia molto all’ultimo esempio, vero? Infatti è il miglioramento promesso; con le tecniche appena viste, controlla che i due separatori siano coerenti.
Nota tecnica In Perl, il testo catturato è disponibile anche all’esterno della regexp nelle variabili speciali $1, $2 e via di seguito. In Vim, non si può accedere a più di 9 captures. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Una feature utile
De utilitate \b
/\b(\w+) \W+ \1\b/ Quello che fa questa regexp è scoprire se ci sono parole duplicate nel testo Senza il \b finale, conterebbe duplicati anche in testi come “the light lightsaber”. Senza il \b iniziale, ne troverebbe in “mentre tre . . . ”.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Configurazioni
L’utilità delle captures è ancora più evidente se si pensa a come usarle all’esterno della stessa espressione regolare, in altre parti del programma. Pensiamo ad esempio di dover lavorare con un semplice file di configurazione chiave-valore, ad esempio di questo formato : property = user choice Possiamo fare semplicemente il parsing del file, per inserire i dati in un array associativo (gli hash del Perl o i dizionari del Python): /(\w+)\s*=\s*(.+)/ $configurazione{$1} = $2;
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Configurazioni
sources.list4 /ˆdeb(-src)? ([ˆ\s]+)\s+(\w+)\s+ ((?:main\s*|contrib\s*|non-free\s*)+)/
4 Supponendo che i campi siano divisi da spazi; credo che di default sia così RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Configurazioni
sources.list4 /ˆdeb(-src)? ([ˆ\s]+)\s+(\w+)\s+ ((?:main\s*|contrib\s*|non-free\s*)+)/ \1 È non nulla solo se l’entrata è deb-src \2 Contiene l’url del repository (ok, è un po’ lasco come matching) \3 Contiene il ramo di distribuzione : stable-testing-unstable (. . . Ubuntu? . . . cos’è?) \4 Contiene la combinazione di main-contrib-non-free che è presa da quel repo. (notare che le parentesi più interne non catturano) 4 Supponendo che i campi siano divisi da spazi; credo che di default sia così RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Configurazioni
/etc/passwd /ˆ(.+?):(?:.*):(.+)$/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Configurazioni
/etc/passwd /ˆ(.+?):(?:.*):(.+)$/ \1 Contiene lo username \2 Contiene la shell di login Potremmo quindi usarlo per avere la lista di utenti con shell di login valida, o qualcosa del genere.a a
Ovviamente per scopo di ricerca; le regexp infatti smetteranno di funzionare automagicamente se usate per fini illeciti :D
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
L’ingordigia porta al lato oscuro - 1/2 Qualcuno ha notato qualcosa di strano nell’ultimo esempio? Il trucco è nel come fermarsi ai primi “:” /ˆ(.+?):(?:.*):(.+)$/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
L’ingordigia porta al lato oscuro - 1/2 Qualcuno ha notato qualcosa di strano nell’ultimo esempio? Il trucco è nel come fermarsi ai primi “:” /ˆ(.+?):(?:.*):(.+)$/
Greedy I quantificatori * e + hanno un comportamento greedy (in italiano, più o meno, ingordo), nel senso che “mangiano” testo fino a quando è loro possibile. In altri termini, date più alternative per fare il match del testo, sarà scelta sempre la più lunga.
? Far seguire un quantificatore da un ? cambia questo comportamento, facendo optare per il primo match possibile (si parla di lazy quantifier). RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
L’ingordigia porta al lato oscuro - 2/2 Esempio semplice Do, or do not.
There is no try.
Dato questo testo, possiamo provare a catturare del testo in due modi diversi e vedere le differenze: /(.*)do/i /(.*?)do/i Greedy \1 contiene “Do, or ”. Non-greedy \1 è la stringa vuota. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
Valid xhtml /\<(.+?)\b.*?\>.*\<\/\1\>/
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
Valid xhtml /\<(.+?)\b.*?\>.*\<\/\1\>/ Cosa fa Controlla che il tag venga chiuso prima o poi. ?-1 Il primo ? serve per smettere di catturare subito dopo la conclusione del nome del tag - sarà quello che controlliamo alla fine. ?-2 Il secondo ? serve per essere sicuri di non andare oltre la fine del tag in cui siamo attualmente, cercandone le opzioni.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Greedy matching
Possessive Esiste anche la deviazione opposta dal comportamento greedy; si parla di quantificatori possessivi. Sintassi Basta far seguire il quantificatore da un + Comportamento Il quantificatore “mangia” tutto quello che è possibile, ma al contrario de greedy, se questo fa fallire l’espressione regolare, non vengono tentati step intermedi.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Yet another boring example
Le basi Un’altra abilità built-in nelle regex è quella di sostituzione del testo. Usarla nella sua forma base è piuttosto semplice, basta una sintassi del tipo : s/Anakin Skywalker/Darth Vader/g /g Il modificatore finale sta per “global”; indica all’espressione di sostituire ogni occorrenza trovata Ed ecco che l’identità passata è al sicuro :D
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Yet another boring example
Date . . . di nuovo Neanche a dirlo, però, la vera utilità è in coppia con le captures appena viste : riprendiamo le nostre amiche date : s/(\d{1,2})(\D)(\d{1,2})\2(\d{2,4})/\4\2\3\2\1/g
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Yet another boring example
Date . . . di nuovo Neanche a dirlo, però, la vera utilità è in coppia con le captures appena viste : riprendiamo le nostre amiche date : s/(\d{1,2})(\D)(\d{1,2})\2(\d{2,4})/\4\2\3\2\1/g
E voilà : convertito un mucchio di date “italiane” in date scritte all’americana, facilmente ordinabili!
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Qualcosa di pratico
BBcode to HTML Ecco un esempio su cui sono inciampato preparando il nuovo sito del MontelLUG : s/\[url=(.*?)\](.*?)\[\/url\]/ \
\2\<\/a\>/g
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Qualcosa di pratico
BBcode to HTML Ecco un esempio su cui sono inciampato preparando il nuovo sito del MontelLUG : s/\[url=(.*?)\](.*?)\[\/url\]/ \\2\<\/a\>/g Cosa fa Converte i tag url del bbcode in link html. Limitazioni Se si usa, invece di [url=link]descrizione[/url], la forma [url]link === descrizione[/url], il comportamento è non corretto; migliorarlo è lasciato come esercizio per il lettore :D
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Qualcosa di pratico
Wiki to LATEX Traduzioni Ormai, il potenziale delle espressioni regolari come “traduttori automatici” (non di linguaggio naturale, per quanto ne sappia :D) dovrebbe essere chiaro.
Modalità SPAM on Nonostante sia squallida autopromozione, un altro esempio interessante che è un po’ troppo complesso da mostrare e discutere qui (anche perché è più Perl che regexp pure) è un traduttore mediawiki to LATEX e html, che ho scritto tempo fa e che potrei linkare agli interessati, alla fine. RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Qualcosa di pratico
Sostituzione in vim Find-replace A meno di interfacce grafiche come gvim, la sostituzione con espressioni regolari è il metodo principale in Vim. Sintassi La sintassi base del comando è :riga_inizio,riga_fine s/from/to/modifiers /c In vim, il modificatore /c finale sta per Confirm, chiede conferma prima di eseguire la sostituzione. Attenzione perché uno /c esiste anche nelle regexp standard, con tutt’altro significato.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Look around
Zero-width Riprendiamo l’esempio di apt/sources.list; vogliamo controllare in modo esplicito che la riga non sia un commento : il file è bash-style, quindi controlliamo che non inizi con caratteri #; sarebbe sensato pensare di scrivere : /ˆ[ˆ#]deb ...resto della regexp/ Sorprendentemente, non funziona.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Look around
Zero-width Riprendiamo l’esempio di apt/sources.list; vogliamo controllare in modo esplicito che la riga non sia un commento : il file è bash-style, quindi controlliamo che non inizi con caratteri #; sarebbe sensato pensare di scrivere : /ˆ[ˆ#]deb ...resto della regexp/ Sorprendentemente, non funziona. consumo Infatti, il [ˆ#] comunque consuma un carattere, cioè la d con cui inizierebbe una riga regolare, quindi il deb successivo non matcha più zero-width Gli unici casi visti finora che non “consumano” caratteri sono ˆ, $ e \b RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Look around
Look-ahead e look-behind Una soluzione esiste; si tratta di usare una tecnica chiamata look-ahead, che esegue il controllo voluto, ma senza consumare caratteri. Ecco l’esempio (in due versioni): /ˆ(?=[ˆ#])deb .../ /ˆ(?!#)deb .../ Come esiste il look-ahead, c’è il look-behind per controllare prima della posizione attuale, che è il principio su cui si basa il ˆ; ecco infatti una sintassi equivalente a ˆ. /(?
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Verso l’infinito . . .
Split Giusto per completezza, un tool fondamentale che funziona grazie alle espressioni regolari : split (regex, stringa) Restituisce una lista creata dividendo la stringa ogni volta che la regexp trova un match. Il caso semplice è quando la regex è una stringa letterale : torniamo all’esempio di /etc/passwd; possiamo ricavare l’intera lista di campi : split (“:”, $file) Lo split con semplice doppio parametro string esiste più o meno in ogni linguaggio di programmazione.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
Verso l’infinito . . .
tr/// Infine, come alternativa alla sostituzione tramite regex, esiste (anche come utility in command line, ma con sintasi diversa) tr che con una sintassi simile a s///g permette di eseguire semplici traslitterazioni di caratteri. tr/0-9/A-J/ Questo, ad esempio, traduce le cifre in caratteri. Il - ha il solito significato di “intervallo” in Perl.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
. . . e oltre
Un sacco di roba che non so “It is against my programming to impersonate a deity” - C3P0
C’è molto di più, e molto che non so, quindi, magari partendo da questa bibliografia, potrete scoprire molte altre cose.
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
. . . e oltre
Letture consigliate per approfondire. . .
Perldoc perldoc perlretut perldoc perlre Online http://www.regular-expressions.info
RegExp Intro
MontelLUG
Introduzione
Matching
Captures
Sostituzione
Cos’altro c’è
. . . e oltre
Thus endeth . . . Bene, Grazie a tutti per aver sopportato me e le mie citazioni da Star Wars :D
Happy hacking!
RegExp Intro
MontelLUG