Le Espressioni Regolari e gli Automi

50
:: Espressioni Regolari :: Linguaggi ed applicazioni Università degli Studi di Salerno Corso di Automi, Linguaggi e Complessità Maggio 2016 Autori: Giuseppe Luciano, Christian Ronca Docente: Prof.ssa Margherita Napoli

Transcript of Le Espressioni Regolari e gli Automi

Page 1: Le Espressioni Regolari e gli Automi

:: Espressioni Regolari :: Linguaggi ed applicazioni

Università degli Studi di Salerno Corso di Automi, Linguaggi e Complessità

Maggio 2016

Autori: Giuseppe Luciano, Christian Ronca

Docente: Prof.ssa Margherita Napoli

Page 2: Le Espressioni Regolari e gli Automi

Indice

• Introduzione

• Espressioni Regolari e Automi

• ER nei linguaggi di programmazione

• ER nei compilatori

Espressioni regolari, linguaggi ed applicazioni mag. ’16 2

Page 3: Le Espressioni Regolari e gli Automi

Introduzione

Espressioni Regolari

Le espressioni regolare sono un modo semplice per capire se una stringa rispetta un certo formato: email, numeri di telefono, indirizzi IP, ecc.

Sono strettamente legate agli automi a stati finiti e possono rappresentare un’alternativa alla notazione degli automi a stati finiti per descrivere componenti software;

Con le ER si possono definire tutti e soli i linguaggi regolari.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 3

Page 4: Le Espressioni Regolari e gli Automi

Introduzione

Storia

• Verso la fine degli anni 60, Stephen Kleene formalizza i linguaggi regolari usando la nozione matematica «regular sets»;

• Nel 1962, fu creato SNOBOL che non utilizzava le espressioni regolari, ma un proprio modello di matching;

• Nel 1968, le espressioni regolari vengono usate all’interno di un editor di testo per fare pattern matching e come analizzatore lessicale in un compilatore;

• Successivamente vengono integrate nei programmi Unix (come grep) ed in altri sistemi; vengono standardizzate nello standard POSIX 2 nel 1992;

• Nel 1980 vengono introdotte in PERL e nel 1997 viene sviluppata PCRE da Philip Hazel, una libreria per espressioni per PERL utilizzata da numerosi programmi come ad esempio APACHE.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 4

Page 5: Le Espressioni Regolari e gli Automi

Introduzione

Espressioni regolari, linguaggi ed applicazioni mag. ’16 5

Page 6: Le Espressioni Regolari e gli Automi

Introduzione

Espressioni regolari, linguaggi ed applicazioni mag. ’16 6

Page 7: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Le espressioni regolari (”Regular Expression”) garantiscono un metodo efficace e flessibile per l’elaborazione del testo.

Le espressioni regolari sono uno strumento indispensabile per i linguaggi di programmazione che gestiscono le stringhe, soprattutto per analizzarle.

Un linguaggio di programmazione per usare le R.E. ha bisogno di un Regular Expression Engine.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 7

Page 8: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Engine

Un Engine è un motore che prende in input una stringa e un criterio di accettazione (o pattern) e restituisce uno tra:

• DFA • NFA Tradizionale • POSIX NFA

Tutte le engine provano a trovare il match leftmost più lungo, ma questo può cambiare a seconda del tipo di engine.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 8

Page 9: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Costruzione di Engine: l'algoritmo di Thompson

Per costruire un engine ci sono diversi algoritmi.

Quello più famoso è l'algoritmo di Thompson, usato per trasformare un’espressione regolare in un automa equivalente non deterministico (NFA).

Espressioni regolari, linguaggi ed applicazioni mag. ’16 9

Page 10: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Esempi di Engine

Gli Engine DFA sono usati da MySql, Awk e operano in tempo lineare.

Il matching è detto ”text-direct”, man mano che i caratteri in input vengono letti, viene aggiornata una lista dei possibili match.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 10

Page 11: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Esempi di Engine Gli Engine NFA Tradizionali sono usati dai linguaggi di programmazione

tradizionali. Caratteristiche:

• Esegue algoritmi più rigidi per la ricerca di testo con funzionalità di backtracking.

• Verifica tutte le possibili espansioni di un’espressione regolare in un determinato ordine e accetta la prima corrispondenza.

• Nei casi peggiori si può assistere a rallentamenti di carattere esponenziale. E’ conveniente ottimizzare la regexpr.

• Viene detto ”regex-direct”.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 11

Page 12: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Esempi di Engine

POSIX NFA • È simile al modulo di gestione NFA tradizionali, con la sola eccezione

che continua il backtracking fino a maturare la certezza di aver trovato la corrispondenza più lunga

• Di conseguenza, un modulo di gestione POSIX NFA è più lento di un modulo di gestione NFA tradizionale

• Non è possibile favorire l’individuazione di una corrispondenza più breve rispetto a una più lunga modificando l’ordine di ricerca del backtracking.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 12

Page 13: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi

Esempi di Engine

Engine ibridi DFA/NFA sono usati da GNU awk, GNU egrep and Tcl L’unica implementazione pienamente ibrida è quella sviluppata da

Henry Spencer (1) per Tcl. Egrep e awk usano due engine separati, scelti a seconda della presenza

di determinate caratteristiche nell'espressione regolare 1: https://garyhouston.github.io/regex/

Espressioni regolari, linguaggi ed applicazioni mag. ’16 13

Page 14: Le Espressioni Regolari e gli Automi

Espressioni regolari e automi: Esempio

Parola: oneselfsufficient

RegEx: /one(self)?(selfsufficient)?/

Con NFA normale si deve ottimizzare il pattern di match, per trovare il pattern leftmost più lungo.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 14

Nfa

oneself

Posix Nfa

oneselfsufficient

Page 15: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Le espressioni regolari sono costituite da un sottoinsieme di Metacaratteri, che sono caratteri speciali che rappresentano un insieme di altri caratteri o sequenze di caratteri. Es: Riconoscimento di un indirizzo e-mail:

Espressioni regolari, linguaggi ed applicazioni mag. ’16 15

Page 16: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Quantificatori: si inseriscono dopo il pattern e danno un’indicazione di quante volte ricercare una sequenza di caratteri: • + : una o più occorrenze;

• * : 0 o più occorrenze;

• ? : 0 o 1 sola occorrenza, es: A?

• {n}, {2,4} : n occorrenze;

NB: “?” può avere diversi significati a seconda di dove viene usato.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 16

Page 17: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Ancore: identificano la posizione in cui cercare testo (^, $, \b). Es: • ^(il|la): stringhe che cominciano con «il» o «la»; • \d*$: stringhe che finiscono con numeri decimali; • \b (boundary) identifica il confine delle parole. Es: \bcat identifica 'cat'

all'inizio di ogni parola, mentre cat\b identifica 'cat' alla fine di ogni parola.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 17

Page 18: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Classi: indicano un elenco di caratteri da ricercare e vengono racchiusi tra parentesi quadre. E’ possibile inserire anche degli intervalli di ricerca tramite il segno ‘-’ (es: [abc], [a-z], ecc);

Espressioni regolari, linguaggi ed applicazioni mag. ’16 18

Page 19: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Gruppi: vengono racchiusi tra parentesi tonde e vengono richiamati nel caso in cui avviene una sostituzione o per indicare una sottostringa. Nei gruppi è possibile usare anche l’operatore | (or). Es: c(o|a)sa.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 19

Page 20: Le Espressioni Regolari e gli Automi

mag. ’16 Espressioni regolari, linguaggi ed applicazioni 20

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare? Non-capturing subpattern - ?: Se facessimo il match della stringa "the red king“ con l'espressione regolare "the ((red|white) (king|queen))" le sottostringhe estratte sarebbero: "red king", "red" e "king". Se non vogliamo catturare un sub-pattern, si deve usare ?: davanti alle parentesi tonde, che vanno ad indicare il gruppo (in inglese subpattern). Infatti dalla stringa "the white queen" matchata con l'espressione "the ((?:red|white) (king|queen))" si prenderebbero solo le sottostringhe: "white queen" and "queen"

Page 21: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Come è fatta un’espressione regolare?

Asserzioni Look-around: elementi di controllo che vengono applicati alle ricerche. • (?=abc): positive lockahead. L’engine non si sposta avanti sul pattern. • (?<=abc): positive lookbehind. Es: “(?<=a)b” - seleziona una b preceduta da un a • (?!abc): negative lockahead. Es: “b(?!a)” - b non seguita da a • (?<!abc): negative lookbehind. Es: “(?<!a)b“ - a non precede b Altri esempi: http://www.regular-expressions.info/refadv.html

Espressioni regolari, linguaggi ed applicazioni mag. ’16 21

Page 22: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

altri metacaratteri sono:

• Caratteri speciali: identificano caratteri come quelli di fine riga, tabulazioni o escape (\n, \r, \t, \*, \\, ecc..);

• Classi di carattere: specificano una serie di caratteri senza l’utilizzo dei gruppi.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 22

Page 23: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Prestazioni: come ottimizzare un E.R.

A seconda dell’engine usato ci possono essere dei pattern che lavorano meglio o peggio;

Ci sono delle regole generiche che servono a migliorare le performance.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 23

Page 24: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Prestazioni: come ottimizzare un E.R.

Genericamente si può dire che • le costruzioni più semplici sono più efficienti di altre:

• [aeiou] è più efficiente di (a|e|i|o|u)

• I pattern più lunghi di solito sono quelli più efficienti.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 24

Page 25: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Prestazioni: come ottimizzare un E.R.

Più precisamente è consigliabile usare:

1. Le classi di caratteri. Specificare quale classi di caratteri usare (es: [a-z] o [0-9] ) invece di usare .*,

così da evitare il backtracking

2. I quantificatori Lazy dove richiesto: Es: “.* Lock_time” o “.*? Lock_time” ? Col primo pattern viene letta tutta la

frase e poi viene eseguito un backtrack (si va a ritroso) fino al primo “Lock_time”; col secondo viene letta la frase fino a “Lock_time”.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 25

Page 26: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Prestazioni: come ottimizzare un E.R.

Il backtracking: lazy e greedy matching

Espressioni regolari, linguaggi ed applicazioni mag. ’16 26

Page 27: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Implementazione:

In quasi tutti i linguaggi di programmazione le espressioni regolari vengono prima compilate (viene generato l’automa corrispondente) e poi viene eseguito il match sulle stringhe.

Solo in Perl ci sono degli operatori di pattern binding: • =~ se uguale • ! ~ se diverso

che permettono di applicare le espressioni regolari senza compilarle prima.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 27

Page 28: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Java

Espressioni regolari, linguaggi ed applicazioni mag. ’16 28

Page 29: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Python

Espressioni regolari, linguaggi ed applicazioni mag. ’16 29

Page 30: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Perl

#/user/bin/perl $string = 'The cat sat on the mat'; $string =~ s/cat/dog/; print "$string\n";

Questo codice stampa: The dog sat on the mat

Espressioni regolari, linguaggi ed applicazioni mag. ’16 30

Page 31: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

PCRE - Perl Compatible Regular Expressions

La libreria PCRE è stata scritta in C da Philip Hazel ed implementa le funzionalità di pattern matching tramite espressioni regolari, usando la stessa sintassi e semantica di Perl 5. La sintassi di PCRE è molto più potente e flessibile dello standard POSIX e molte altre librerie di espressioni regolari (ad esempio: ereg). PCRE non viene usata solo da PERL, ma anche da Apache, PHP, KDE, Postfix, Analog, e Nmap.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 31

Page 32: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Pattern Modifier

PCRE supporta i modificatori di criterio, ovvero, è possibile dare delle direttive alle espressioni regolari come: • i: non viene fatta nessuna distinzione tra caratteri maiuscoli e minuscoli; • m: la ricerca avviene su più linee, non si ferma alla prima occorrenza; • x: vengono ignorati gli spazi; • u: la stringa di ricerca viene considerata come utf-8; • g: ricerca globale; • …

Non tutti i linguaggi supportano questi valori di flag.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 32

Page 33: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Supporto delle abbreviazioni: in PCRE è possibile individuare lettere o numeri

attraverso le seguenti abbreviazioni:

\d equivale a [0-9]

\D nega la precedente [^0-9]

\w equivale a [0-9A-Za-z]

\W nega la precedente [^0-9A-Za-z]

\s equivale a [ \t\n\r]

\S nega la precedente [^ \t\n\r]

Espressioni regolari, linguaggi ed applicazioni mag. ’16 33

Page 34: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Extended character classes: PCRE supporta le classi di caratteri a lettera

singola, ovvero tramite il carattere ‘\d’, è possibile identificare tutte le cifre da 0-9, con ‘\w’ tutte le parole dell’alfabeto a-z, ecc (es: in POSIX si usa [[:digit:]]);

• Lazy matching (a.k.a. “ungreedy”): Tramite l’uso del carattere ‘?’ è possibile

velocizzare il matching.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 34

Page 35: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Unicode character properties: è possibile definire delle regole per la gestione

dei caratteri Unicode. Per esempio, con il carattere ‘\w’, è possibile riconoscere tutte le stringhe di caratteri letterali. Inserendo( *UCP) all’inizio del pattern, è possibile alterare la proprietà di ‘\w’ estendo il supporto anche ai caratteri accentati e speciali;

• Multiline matching: ^ e $ possono corrispondere all’inizio e la fine di una

stringa, oppure specificare l’inizio e la fine di una linea di caratteri presenti all’interno della stringa a seconda delle opzioni che sono state impostate.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 35

Page 36: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Newline/linebreak options: è possibile specificare tramite PCRE tutti i caratteri

speciali che indicano l’inizio o l’interruzione e a capo di una stringa.

Per esempio: • (*LF) che corrisponde a \r;

• (*CR) che corrisponde a \n: fine stringa;

• (*ANYCRLF) che corrisponde a (?>\r\n|[\r\n]) oppure \R;

• (*ANY) che corrisponde a (?>\r\n|\n|\x0b|\f|\r|\x85) o \R ed include il supporto a UTF-8;

Espressioni regolari, linguaggi ed applicazioni mag. ’16 36

Page 37: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Atomic grouping : è un modo di prevenire il backtracking in un pattern. Ad

esempio, ‘a++’ prenderà tutte le ‘a’ all’interno di un insieme di stringhe senza mai fare backtracking. In pratica, la selezione avviene solo quando ci sono un certo numero di ‘a’ seguite da un altro carattere.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 37

Page 38: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Recursive patterns: può

capitare che si è interessati a verificare che in una stringa, per lo stesso numero di parentesi aperte, ci sia lo stesso numero di parentesi chiuse.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 38

Page 39: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Feature di PCRE

• Tricks: è possibile individuare tutte le stringhe che sono composte da 3 caratteri o che hanno una lunghezza multipla di 3;

Espressioni regolari, linguaggi ed applicazioni mag. ’16 39

Page 40: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Domini applicativi

grep (general regular expression print) è un comando dei sistemi Unix e Unix-like, e più in generale dei sistemi POSIX e GNU, che ricerca in uno o più file di testo le linee che corrispondono ad uno o più modelli specificati con espressioni regolari o stringhe letterali, e produce un elenco delle linee (o anche dei soli nomi di file) per cui è stata trovata corrispondenza.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 40

Page 41: Le Espressioni Regolari e gli Automi

ER nei linguaggi di programmazione

Domini applicativi http://www.regexpal.com/ E’ un servizio web che offre la possibilità di testare e debuggare la correttezza delle espressioni regolari. Ci sono numerosi servizi che offrono la stessa cosa come: • http://regexr.com/ • https://regex101.com/ • Altri…

Espressioni regolari, linguaggi ed applicazioni mag. ’16 41

Page 42: Le Espressioni Regolari e gli Automi

ER nei compilatori

Le espressioni regolari ricoprono un ruolo cruciale nella progettazione di un compilatore!

Presupposto: Un compilatore è diviso in diverse componenti • Lexer: scansiona l’input in cerca di lessemi;

• Parser: analizza la struttura sintattica del sorgente;

• Semant: analizza la struttura semantica del sorgente;

• Generatore di codice: dato l’albero semantico genera il codice eseguibile.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 42

Token Lexer

Syntax Tree Parser

Syntax Tree Seman

Codice intermedio Code

Generator

Page 43: Le Espressioni Regolari e gli Automi

ER nei compilatori

Il componente che ci interessa è il Lexer:

• Prende il codice sorgente come un flusso di caratteri, lo scansiona alla ricerca di lessemi

• Per ogni lessema restituisce un token al parser, cioè una coppia <Nome, Valore>

Il Lexer opera come un DFA!

Espressioni regolari, linguaggi ed applicazioni mag. ’16 43

Page 44: Le Espressioni Regolari e gli Automi

ER nei compilatori

Come si progetta un Lexer? Ci sono due modi:

1. Pensare a un DFA per leggere i token e implementarlo;

2. Scrivere Espressioni Regolari per riconoscere i token ed usare un lexer-generator per convertirli in un DFA.

Meglio il secondo caso: è più facile!

Espressioni regolari, linguaggi ed applicazioni mag. ’16 44

Page 45: Le Espressioni Regolari e gli Automi

ER nei compilatori

Come si definiscono le espressioni regolari

Le Definizioni regolari sono una sequenza del tipo: • d1 -> r1

• d2 -> r2

dove di è un nuovo simbolo non appartenente all’alfabeto Γ e ri è un’espressione regolare sull’alfabeto: Γ U {d1, d2, …di-1}

• Così si evita la ricorsione!

Espressioni regolari, linguaggi ed applicazioni mag. ’16 45

Page 46: Le Espressioni Regolari e gli Automi

ER nei compilatori

Un lexer generator

JFLEX: • JFLEX è un analizzatore lessicale che prende come input un insieme di

espressioni regolari e delle azioni da effettuare, per generare un programma che legge un testo in input, che fa un match del testo tramite le espressioni regolari e che esegue un’azione sul testo riconosciuto.

• I lexer Flex sono basati su automi deterministici finiti (DFA). Sono molto veloci e non fanno molto backtracking.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 46

Page 47: Le Espressioni Regolari e gli Automi

ER nei compilatori

JFLEX: Come si definisce una definizione regolare

RegExp ::= RegExp '|' RegExp

| RegExp RegExp

| '(' RegExp ')' | ('!'|'~') RegExp

| RegExp ('*'|'+'|'?')

| RegExp "{" Number ["," Number] "}"

| CharClass | PredefinedClass | MacroUsage

| '"' StringCharacter+ '"' | Character

Espressioni regolari, linguaggi ed applicazioni mag. ’16 47

Page 48: Le Espressioni Regolari e gli Automi

ER nei compilatori

JFLEX: Le regole e le azioni LineTerminator = \r|\n|\r\n

WhiteSpace = {LineTerminator} | [ \t\f]

Identifier = [:jletter:] [:jletterdigit:]*

DecIntegerLiteral = 0 | [1-9][0-9]*

<YYINITIAL> "abstract" { return symbol(sym.ABSTRACT); }

<YYINITIAL> "boolean" { return symbol(sym.BOOLEAN); }

<YYINITIAL> "break" { return symbol(sym.BREAK); }

.

Espressioni regolari, linguaggi ed applicazioni mag. ’16 48

STATO EXPR AZIONE

Page 49: Le Espressioni Regolari e gli Automi

FINE! Grazie per l’attenzione!

Espressioni regolari, linguaggi ed applicazioni mag. ’16 49