Nei dati di elaborazione , un'espressione regolare o regolare l'espressione o espressione normale o modello , è una stringa di caratteri , che descrive, secondo una precisa sintassi, una serie di possibili stringhe di caratteri. Le espressioni regolari sono anche chiamate regex (una parola portmanteau formata dall'espressione regolare inglese ). Le espressioni regolari provengono da teorie matematiche dei linguaggi formali degli anni 40. La loro capacità di descrivere in modo conciso insiemi regolari spiega perché sono state trovate in diversi campi scientifici negli anni del dopoguerra e giustifica la loro adozione nell'informatica . Le espressioni regolari sono oggi utilizzate per programmare software con funzionalità di lettura, controllo, modifica e analisi di testi nonché nella manipolazione di linguaggi formali come i linguaggi informatici .
Queste espressioni regolari hanno la qualità di poter essere descritte da formule o pattern, (in inglese patterns ) molto più semplici degli altri mezzi.
Negli anni '40 , Warren McCulloch e Walter Pitts descrissero il sistema nervoso modellando i neuroni mediante semplici automi. Nel 1956, il logico Stephen Cole Kleene descrisse questi modelli in termini di insiemi regolari e automi . È considerato l'inventore delle espressioni regolari. Nel 1959, Michael O. Rabin e Dana Scott hanno offerto il primo trattamento matematico e rigoroso di questi concetti, che è valso loro il Premio Turing nel 1976.
In questo contesto, le espressioni regolari corrispondono alle grammatiche di tipo 3 (vedi Grammatica formale ) della gerarchia di Chomsky ; possono quindi essere usati per descrivere la morfologia di una lingua .
Ken Thompson ha implementato la notazione di Kleene nell'editor qed , poi nell'editor ed in Unix e infine in grep . Da allora, le espressioni regolari sono state ampiamente utilizzate in utilità come lex e nei linguaggi di programmazione nati sotto Unix come expr , awk , Perl , Tcl , Python , ecc.
Uscendo dal quadro teorico, le espressioni regolari hanno acquisito funzionalità che consentono la descrizione di linguaggi non razionali. Si è quindi verificato uno spostamento semantico: la nozione di espressione regolare non ha lo stesso significato nel contesto dell'informatica applicata e nella teoria dei linguaggi formali.
Espressione regolare | Parole descritte | Parole non descritte |
---|---|---|
rilevato | "Rilevato" | "Rilevato", "rilevato", "rilevato", "" |
ex- (a? e | æ | é) quo | “Ex-equo”, “ex-equo”, “ex-aequo” ed “ex-æquo” |
"Ex-quo", "ex-aiquo", "ex-aeko", "ex-æéquo" |
^ Sezione + | “Sezione 1”, “Sezione 22”, “Sezione A”,… |
"Vedi Sezione 1", " Sezione " |
$ 6,66 * | "6.6", "6.666", "6.6666", ... |
"6.66667", |
[1234567890] + (, [1234567890] +)? | "2", "42", "0,618", "49,3", ... |
"3,", ", 75", "" |
Originariamente create per descrivere linguaggi formali, le espressioni regolari sono utilizzate nell'analisi e manipolazione dei linguaggi informatici ; compilatori e interpreti si basano quindi su questi.
Utilizzata come gli strumenti di ricerca del testo in un documento, un'espressione regolare descrive stringhe di caratteri aventi proprietà comuni, al fine di trovarle in un blocco di testo per applicare un trattamento automatizzato, come l'aggiunta, la loro sostituzione, modifica o cancellazione.
Molti editor di testo e la maggior parte degli ambienti di sviluppo integrati supportano le espressioni regolari. Un gran numero di utility Unix sa come usarle in modo nativo. I più noti sono GNU grep o GNU sed che, come gli editor di testo, utilizzano queste espressioni per sfogliare automaticamente un documento alla ricerca di pezzi di testo compatibili con il pattern di ricerca, ed eventualmente per aggiungere, sostituire o eliminare.
Le interfacce a riga di comando (o shell ) utilizzano un sistema correlato ma separato e meno espressivo chiamato glob (en) o globbing.
Le espressioni regolari sono spesso utilizzate nell'amministrazione del sistema , nello sviluppo di software e nelle attività di elaborazione del linguaggio naturale . Hanno visto un nuovo campo di applicazione con lo sviluppo di Internet e la diffusione di codici maligni o messaggi di spam . Di filtri e robot che utilizzano queste espressioni vengono utilizzati per rilevare elementi potenzialmente dannosi.
Nella teoria del linguaggio formale , un'espressione regolare è un'espressione che rappresenta un linguaggio razionale . In questo contesto, le espressioni regolari hanno un potere espressivo più limitato: questa nozione ha un significato più ampio nell'informatica applicata rispetto alla teoria del linguaggio formale.
Un'espressione regolare è una serie di caratteri tipografici (chiamata più semplicemente "pattern" - " pattern " in inglese) che descrive un insieme di stringhe di caratteri . Ad esempio, l'insieme di parole "legato, legato, legato e legato" può essere condensato in un unico modello "ex- (a? E | æ | é) quo". I meccanismi di base per formare tali espressioni si basano su caratteri speciali di sostituzione, raggruppamento e quantizzazione.
Una barra verticale di solito separa due espressioni alternative: "equo | aequo" designa equo o aequo. È inoltre possibile utilizzare le parentesi per definire il campo e la priorità della rilevazione, "(ae | e) quo" che designa lo stesso insieme di "aequo | equo" e quantificare i gruppi presenti nel pattern aggiungendo caratteri di quantizzazione a il diritto di questi raggruppamenti.
I quantificatori più comuni sono:
I simboli con una semantica particolare possono essere chiamati "operatori", "metacaratteri" o "caratteri speciali". I caratteri che rappresentano solo se stessi sono chiamati "letterali".
Le espressioni regolari possono essere combinate, ad esempio per concatenazione , per produrre espressioni regolari più complesse.
Quando una stringa di caratteri corrisponde alla descrizione fornita dall'espressione regolare, diciamo che esiste una "corrispondenza" tra la stringa e il modello, o che il modello "corrisponde" alla stringa. Questa corrispondenza può riguardare tutta o parte della stringa di caratteri. Ad esempio, nella frase “Le due squadre finirono in parità e si salutarono. ", La sottostringa" ex-æquo "è abbinata al modello" ex- (a? E | æ | é) quo ".
Per impostazione predefinita, le espressioni regolari fanno distinzione tra maiuscole e minuscole . Quando possibile, cercano di far corrispondere la sottostringa più grande corrispondente al pattern: si dice che siano “greedy”. Ad esempio, Aa+riconosce l'intera stringa "Aaaaaaa" piuttosto che una parte "Aaa" (ghiottoneria), ma non riconosce la stringa "aaaA" (maiuscole/minuscole).
operatori | Descrizione | Esempi | ||
---|---|---|---|---|
Espressione regolare | catene descritte | Canali non descritti | ||
espr 1 espr 2 | Operatore di concatenazione di due espressioni (implicito). | ab | "Ab" | "A", "b", stringa vuota |
. | Un carattere e uno | . | "A", "b", ecc. | stringa vuota, "ab" |
espr ? | Questo quantificatore corrisponde a ciò che lo precede, presente zero o una volta . Se esistono più corrispondenze in un testo, prima trova quelle poste all'inizio del testo e poi restituisce la massima lunghezza possibile da quella posizione iniziale. | a? | stringa vuota, "a" | "Aa", "b" |
espr + | Questo quantificatore corrisponde a ciò che lo precede, ripetuto una o più volte . Se esistono più corrispondenze in un testo, prima trova quelle poste all'inizio del testo e poi restituisce la massima lunghezza possibile da quella posizione iniziale. | un + | "A", "aa", "aaaaa", ecc. | stringa vuota, "b", "aaab" |
espr * | Questo quantificatore corrisponde a ciò che lo precede, ripetuto zero o più volte . Se esistono più corrispondenze in un testo, trova prima quelle poste all'inizio del testo e quindi restituisce la massima lunghezza possibile da quella posizione iniziale. | a* | stringa vuota, "a", "aaa" e così via. | "B", "aaab" |
espr 1 | espr 2 | È l'operatore di scelta tra più alternative, vale a dire l'unione di insiemi. Può essere combinato il numero di volte necessario per ciascuna delle possibili alternative. Corrisponde a una delle espressioni poste prima o dopo l'operatore . Queste espressioni possono essere facoltativamente vuote, quindi (x |) è equivalente a x ?. | a | b | "A", "B" | stringa vuota, "ab", "c" |
[ elenco ] | Uno dei caratteri tra parentesi quadre ("classe di caratteri") | [a e io o tu] | "A", "e", "i", ecc. | stringa vuota, "b", "ae" |
[^ lista ] | Un carattere non tra parentesi quadre ("classe di caratteri") | [^ aeiou] | "B", ecc. | stringa vuota, "a", "bc" |
( espr. ) | Raggruppare l'espressione tra parentesi | (rilevato) | "Rilevato" | "Rilevato", "rilevato", "rilevato" |
espr { n } | Esattamente n occorrenze dell'espressione che precede le parentesi graffe | un {3} | "Aaa" | "Aa", "aaaa" |
espr { n , m } | Tra n e m occorrenze dell'espressione che precede le parentesi graffe | un {2.4} | "Aa", "aaa", "aaaa" | "A", "aaaaa" |
espr { n ,} | Almeno n occorrenze dell'espressione che precede le parentesi graffe | un {3,} | "Aaa", "aaaa", "aaaaa", ecc. | "Aa" |
^ | Questo predicato non corrisponde ad alcun carattere ma fissa una condizione necessaria che permette di trovare un accordo su ciò che lo segue indicando che deve essere all'inizio di una riga (quindi essere all'inizio del testo di input o dopo un'interruzione di riga) . Non può essere considerato così all'inizio dell'espressione regolare, altrove è considerato letteralmente. Si applica come condizione al resto dell'espressione regolare (e quindi riguarda tutte le alternative rappresentate). | ^ a trova "a" all'inizio della riga, ma non in "ba". | ||
$ | Questo predicato non corrisponde a nessun carattere ma fissa una condizione necessaria che permette di trovare un accordo su ciò che lo precede indicando che deve essere alla fine di una riga (quindi alla fine del testo di input o appena prima di un'interruzione di riga) . Non può essere considerato così alla fine dell'espressione regolare, altrove è considerato letteralmente. Si applica come condizione al resto dell'espressione regolare (e quindi riguarda tutte le alternative rappresentate). | a $ trova "a" alla fine della riga ma non in "ab". |
In informatica, uno strumento per manipolare le espressioni regolari è chiamato motore di espressioni regolari o motore di espressioni regolari . Esistono standard per garantire la coerenza nell'uso di questi strumenti.
Lo standard POSIX offre tre serie di standard:
Anche le espressioni regolari in perl sono uno standard de facto, per la loro ricchezza e potenza espressiva. Pur seguendo il proprio sviluppo, sono ad esempio all'origine della libreria PCRE . ECMAScript propone anche nel documento Standard ECMA-262 uno standard utilizzato ad esempio da JavaScript .
Le notazioni o la loro semantica possono variare leggermente da un motore di espressioni regolari all'altro. Possono rispettare solo parzialmente o parzialmente questi standard o offrire le proprie funzionalità, come GNU o .NET Framework . Le specifiche di ciascuno sono discusse più avanti in questo articolo.
Una classe di caratteri è un insieme di caratteri. Può essere definito in diversi modi:
Si possono realizzare unioni di classi caratteriali: [0-9ab]designa l'insieme composto dai caratteri da “0” a “9” e dalle lettere “a” e “b”. Alcune librerie consentono anche di intersecare le classi di caratteri.
Tra le parentesi quadre, i metacaratteri sono interpretati letteralmente: [.?*]designa l'insieme composto dai caratteri”. ","? "E" * ".
Le classi di caratteri più utilizzate sono generalmente fornite con il motore delle espressioni regolari. Un inventario di queste classi è fatto nella tabella seguente.
La libreria POSIX definisce le classi inizialmente per ASCII e poi, per estensione, per altre forme di codifica dei caratteri, a seconda della localizzazione .
In Unicode e nei linguaggi come perl, i set di caratteri sono definiti attraverso la nozione di proprietà dei caratteri. Ciò consente di designare un insieme di caratteri in base alla loro categoria (esempi: lettera, punteggiatura di apertura, punteggiatura di chiusura, separatore, carattere di controllo), in base alla direzione di scrittura (ad esempio da sinistra a destra o da destra a sinistra), a seconda dell'alfabeto (esempi: latino, cirillico, greco, hiragana); secondo l'allocazione dei blocchi, o anche secondo gli stessi principi delle classi di caratteri POSIX (su questo argomento, leggi la sezione Espressioni regolari e Unicode ).
POSIX | Non standard | perl, Python | Vim | Giava | Unicode | ASCII | Descrizione |
---|---|---|---|---|---|---|---|
\p{ASCII} | [\x00-\x7F] | caratteri ASCII | |||||
[:alnum:] | \p{Alnum} | A-Za-z0-9 | Caratteri alfanumerici | ||||
[:word:] | \w | \w | \w | A-Za-z0-9_ | Caratteri alfanumerici e "_" | ||
\W | \W | \W | ^A-Za-z0-9_ | Personaggi che non inventano parole | |||
[:alpha:] | \a | \p{Alpha} | \p{L} o \p{Letter} | A-Za-z | Caratteri alfabetici | ||
[:blank:] | \s | \p{Blank} | \t | Spazio e tab | |||
\b | \< \> | \b | (?<=\W)(?=\w)|(?<=\w)(?=\W) | Posizioni di inizio e fine delle parole | |||
\B | \B | (?<=\W)(?=\W)|(?<=\w)(?=\w) | Posizioni che non corrispondono all'inizio o alla fine di una parola | ||||
[:cntrl:] | \p{Cntrl} | \p{Cc} o \p{Control} | \x00-\x1F\x7F | Personaggi di controllo | |||
[:digit:] | \d | \d | \p{Digit} o \d | \p{Nd} o \p{Decimal_Digit_Number} | 0-9 | Cifre decimali | |
\D | \D | \D | \P{Nd} o \P{Decimal_Digit_Number} | ^0-9 | Qualcosa di diverso da un decimale | ||
[:graph:] | \p{Graph} | \x21-\x7E | Caratteri visibili Visi | ||||
[:lower:] | \l | \p{Lower} | \p{Ll} o \p{Lowercase_Letter} | a-z | Lettere minuscole | ||
[:print:] | \p | \p{Print} | \x20-\x7E | Caratteri stampabili | |||
[:punct:] | \p{Punct} | \p{P} o \p{Punctuation} | ][!"#$%&'()*+,./:;<=>?@\^_`{|}~- | Caratteri di punteggiatura | |||
[:space:] | \s | \_s | \p{Space} o \s | \p{Z} o \p{Separator} | \t\r\n\v\f | Caratteri spaziali | |
\S | \S | \S | \P{Z} o \P{Separator} | ^ \t\r\n\v\f | Qualcosa di diverso da un carattere spaziale | ||
[:upper:] | \u | \p{Upper} | \p{Lu} o \p{Uppercase_Letter} | A-Z | Lettere maiuscole | ||
[:xdigit:] | \x | \p{XDigit} | A-Fa-f0-9 | Cifre esadecimali | |||
\A | Inizio della stringa di caratteri | ||||||
\Z | Fine della stringa di caratteri |
Ad esempio, nello standard POSIX, fa [[:upper:]ab]corrispondere un carattere tra l'insieme formato da lettere maiuscole e lettere minuscole "a" e "b". Nello standard ASCII, questa espressione regolare verrebbe scritta [A-Zab].
La nozione di classe di equivalenza non deve essere confusa con la nozione di classe di caratteri.
Ad esempio, nella locale FR, la classe [= e =] raggruppa tutte le lettere {e, é, è, ë, ê}.
Ciò significa che quando vengono fascicolate, le lettere {e, é, è, ë, ê} appaiono nello stesso set di caratteri, dopo la d , e prima della f .
La maggior parte degli standard e dei motori di espressioni regolari offre funzioni avanzate. Particolarmente :
Le notazioni utilizzate sono molto variabili. Questo capitolo riunisce da un lato le notazioni specifiche per le diverse implementazioni e, dall'altro, la società di standardizzazione.
Lo standard POSIX ha cercato di porre rimedio alla proliferazione di sintassi e funzionalità fornendo uno standard di espressioni regolari configurabili. Puoi avere una panoramica leggendo il manuale per regexmolti dialetti Unix incluso GNU/Linux . Tuttavia, anche questo standard non include tutte le funzionalità aggiunte alle espressioni regolari Perl.
Infine, POSIX aggiunge il supporto per le piattaforme che utilizzano un set di caratteri non basato su ASCII, in particolare EBCDIC e il supporto locale parziale per alcuni metacaratteri.
Espressioni regolari di baseLe utilità nel mondo Unix come sed , GNU grep , ed o vi utilizzano lo standard BRE (" Basic Regular Expression ") di POSIX per impostazione predefinita . In esso, le parentesi graffe, le parentesi, il simbolo "? "E il simbolo" + "non sono metacaratteri: rappresentano solo se stessi. Per prendere la loro semantica dai metacaratteri, devono essere preceduti dal simbolo "\".
Esempio: l'espressione regolare corrisponde a (ab.)+"(abc) +" ma non a "abcabd", per cui è \(ab.\)\+adatto.
Espressioni regolari estesePOSIX Extended Regular Expression (ERE ) è spesso supportata nelle utilità delle distribuzioni Unix e GNU/Linux includendo il flag -E nell'invocazione della riga di comando di queste utilità. A differenza delle espressioni regolari di base, riconoscono i caratteri precedentemente visti come metacaratteri. Devono quindi essere sfuggiti per essere interpretati letteralmente.
La maggior parte degli esempi qui forniti sono espressioni regolari estese POSIX.
Sequenze di fugaPoiché i caratteri (, ), [, ], ., *, ?, +, ^, |, $, -e \sono usati come simboli speciali, dovrebbero essere referenziati in una sequenza di escape se denotano letteralmente il carattere corrispondente. Questo viene fatto precedendoli con una barra rovesciata \.
Estensioni simili sono usate nell'editor emacs , che usa un diverso insieme di comandi dallo standard POSIX; ma usa le stesse espressioni regolari con una notazione estesa. Le espressioni regolari estese sono ora supportate anche in vim , la versione migliorata di vi .
Operatore esteso (non POSIX) | Descrizione | Esempio |
---|---|---|
\{m,n\} | Nella notazione estesa, questo crea un quantificatore limitato personalizzato, che consente a m di corrispondere esattamente a n occorrenze di quanto sopra, dove m e n sono due numeri interi tali che m < n . Uno dei due parametri può essere omesso: se il primo parametro m viene omesso, il valore predefinito è 0; se il secondo parametro n viene omesso, ma è presente la virgola, si considera infinito; se si omette il secondo parametro n così come la virgola di separazione assume il valore di default uguale al primo parametro m . | Vedere gli esempi di seguito. |
\( \) | Nella notazione estesa, le parentesi di raggruppamento (in una sequenza di escape) vengono utilizzate per delimitare un insieme di alternative o qualsiasi sottoespressione regolare (eccetto le condizioni di inizio e fine riga) per applicare un quantificatore. Inoltre, queste parentesi delimitano un gruppo di cattura numerato che può essere utilizzato per le sostituzioni (facciamo quindi riferimento ai gruppi catturati nella catena di sostituzione con dove n è il numero del gruppo di cattura compreso tra 1 e 9, l'intera catena trovata è rappresentata da ). $n$& | Vedere gli esempi di seguito. |
Inoltre, vengono aggiunte molte altre sequenze di escape per indicare classi di caratteri predefinite. Sono specifici per ogni utilità o talvolta variano a seconda della versione o della piattaforma (comunque sono stati stabili per molto tempo in emacs che è stato un precursore di queste estensioni, che altri autori hanno implementato parzialmente in modo limitato o diverso).
Python utilizza espressioni regolari basate su espressioni regolari POSIX, con alcune estensioni o differenze.
Gli articoli compatibili POSIX sono i seguenti:
La sequenza \bdesigna il carattere backspace ( 0x08con codifica compatibile con ASCII) quando viene utilizzato all'interno di una classe di caratteri e il confine di una parola in caso contrario.
Il sistema operativo BSD utilizza la libreria regex scritta da Henry Spencer . Compatibile con lo standard POSIX 1003.2, questa libreria è utilizzata anche da MySQL (con gli operatori REGEXP e NOT REGEXP) e PostgreSQL (con l'operatore “~” e sue varianti).
Il motore delle espressioni regolari del linguaggio Tcl deriva da sviluppi di Henry Spencer successivi a quelli della libreria BSD. Le espressioni regolari sono chiamate espressioni regolari avanzate (o ARE) e sono leggermente diverse dalle espressioni regolari estese in POSIX. Sono supportate anche le espressioni regolari di base ed estese.
A differenza di altri motori, questo funziona su base PLC, il che lo rende meno efficiente quando sono necessarie acquisizioni o backtracking , ma più efficiente in caso contrario.
Perl offre un set di estensioni particolarmente ricco. Questo linguaggio di programmazione ha molto successo grazie alla presenza di operatori di espressioni regolari inclusi nel linguaggio stesso. Le estensioni che offre sono disponibili anche per altri programmi con il nome lib PCRE ( Perl-Compatible Regular Expressions , letteralmente libreria di espressioni regolari compatibili con Perl ). Questa libreria è stata originariamente scritta per il server di posta Exim , ma ora è stata rilevata da altri progetti come Python , Apache , Postfix , KDE , Analog , PHP e Ferite .
Le specifiche Perl 6 regolarizzano ed estendono il meccanismo del sistema delle espressioni regolari. Inoltre è meglio integrato nel linguaggio che in Perl 5. Il controllo del ritorno sulla traccia è molto fine. Il sistema regex di Perl 6 è abbastanza potente da scrivere parser senza usare plug-in di parser . Le espressioni regolari sono una forma di subroutine e le grammatiche sono una forma di classe . Il meccanismo è implementato in Parrot assembler dal modulo PGE nell'implementazione Parrot di Perl 6 e in Haskell nell'implementazione Pugs . Queste implementazioni sono un passo importante nella costruzione di una completa Perl 6 compilatore . Alcune delle funzionalità di regexp di Perl 6, come le acquisizioni denominate, sono integrate a partire da Perl 5.10.
PHP supporta due forme di notazione: la sintassi POSIX (POSIX 1003.2) e quella, molto più ricca ed efficiente, della libreria PCRE (Perl Compatible Regular Expression).
Uno dei difetti criticati in PHP è relativo al suo limitato supporto per le stringhe di caratteri, anche se viene utilizzato principalmente per elaborare il testo, poiché il testo può essere rappresentato solo in un insieme di caratteri codificati su 8 bit, senza poter specificare chiaramente quale viene utilizzata la codifica. In pratica è quindi necessario aggiungere al PHP librerie di supporto per la codifica e la decodifica dei testi, anche solo per rappresentarli in UTF-8. Tuttavia, anche in UTF-8, il problema sorge immediatamente con la semantica delle espressioni regolari poiché i caratteri hanno quindi una codifica a lunghezza variabile, che richiede di rendere più complesse le espressioni regolari. Vengono quindi sviluppate estensioni PHP opzionali per creare un nuovo tipo di dati per il testo, al fine di facilitarne l'elaborazione (ed eventualmente essere compatibili con Perl6 che, come Haskell , avrà nativamente il pieno supporto Unicode).
ICU definisce una libreria portatile per l'elaborazione di testi internazionale. Questo è inizialmente sviluppato in linguaggio C (versione denominata ICU4C) o per la piattaforma Java (versione denominata ICU4J). I port (o adattamenti) sono disponibili anche in molti altri linguaggi, utilizzando la libreria sviluppata per il linguaggio C (o C++ ).
Le espressioni regolari che possono essere utilizzate in ICU prendono le caratteristiche delle espressioni regolari in Perl, ma le integrano per fornire loro pieno supporto per il set di caratteri Unicode (vedi la sezione successiva per le domande relative alla standardizzazione ancora in corso). Inoltre chiariscono il loro significato rendendo le espressioni regolari indipendenti dal set di caratteri codificato utilizzato nei documenti, poiché il set di caratteri Unicode viene utilizzato come codifica pivot interna.
Questo perché le espressioni regolari Perl (o PCRE) non sono portabili per l'elaborazione di documenti che utilizzano set di caratteri codificati diversi, né supportano correttamente set di caratteri codificati multibyte (lunghezza variabile) come ISO 2022 , Shift-JIS o UTF-8 ) , o codificati su una o più unità binarie di più di 8 bit (ad esempio UTF-16 ) poiché la codifica effettiva di questi insiemi come sequenze di byte dipende dalla piattaforma. word di più di 8 bit).
ICU risolve questo problema adottando un'elaborazione che utilizza internamente un unico set di 32 bit e supporta il full universal character set (UCS), come definito in ISO/IEC 10646 e semanticamente specificato nello standard Unicode (che aggiunge allo standard il supporto di proprietà informative o normative sui caratteri e raccomandazioni per l'elaborazione automatica del testo, alcune di queste raccomandazioni sono facoltative o informative, altre sono diventate standard e integrate nello stesso standard Unicode, altre infine hanno acquisito lo status di standard internazionale presso ISO o standard nazionale in alcuni paesi).
ICU supporta le seguenti estensioni, direttamente nelle espressioni regolari o nell'espressione regolare di una classe di caratteri (tra […]):
Le espressioni regolari ICU sono attualmente tra le più potenti ed espressive nell'elaborazione di documenti multilingue. Sono in gran parte la base della standardizzazione (ancora in corso) delle espressioni regolari Unicode (vedi sotto) e un sottoinsieme è nativamente supportato nella libreria di linguaggi Java standard (che utilizza internamente un set di caratteri portabile a codifica variabile, basato su UTF-16 con estensioni e le cui unità di codifica sono 16 bit).
ICU è una libreria in continua evoluzione. In linea di principio, dovrebbe adottare tutte le estensioni annunciate in Perl (incluse le catture denominate), al fine di garantire l'interoperabilità con Perl 5, Perl 6 e PCRE e il numero crescente di altri linguaggi che utilizzano questa sintassi estesa, e gli autori di ICU e Perl stanno lavorando insieme per definire una notazione comune. Tuttavia, ICU adotta principalmente le estensioni adottate nelle espressioni regolari descritte nello standard Unicode, poiché ICU funge da riferimento principale in questo allegato allo standard Unicode.
Tuttavia, non esiste ancora uno standard o uno standard tecnico per affrontare alcuni aspetti importanti delle espressioni regolari in un contesto multilingue, tra cui:
Per chiarire questi ultimi aspetti mancanti, dovrebbero poter essere utilizzati metacaratteri aggiuntivi per controllare o filtrare le occorrenze trovate, oppure un ordine standardizzato imposto all'elenco delle occorrenze restituite. Gli autori delle applicazioni devono quindi essere vigili su questi punti e assicurarsi di leggere tutte le occorrenze trovate e non solo la prima, per poter decidere quale delle occorrenze è la più appropriata per una data operazione.
Le espressioni regolari sono state originariamente utilizzate con caratteri ASCII . Molti motori di espressioni regolari ora possono gestire Unicode . In molti modi, il set di caratteri codificato utilizzato non fa differenza, ma sorgono alcuni problemi nell'estendere le espressioni regolari per Unicode.
Una domanda è quale formato di rappresentazione Unicode interno è supportato. Tutti i motori di espressioni regolari della riga di comando si aspettano UTF-8 , ma per le librerie alcuni si aspettano anche UTF-8, ma altri si aspettano solo un gioco codificato UCS-2 (o anche la sua estensione UTF-16 che limita anche le sequenze valide), o su UCS- 4 solo (vedi la sua restrizione UTF-32 standardizzata ).
Una seconda domanda è se è supportato l'intero intervallo di valori di una versione di Unicode. Molti motori supportano solo Basic Multilingual Plane , ovvero caratteri codificabili a 16 bit. Solo pochi motori possono (dal 2006) gestire gli intervalli di valori Unicode a 21 bit.
Una terza domanda è come i costrutti ASCII vengono estesi a Unicode.
Tuttavia, in pratica spesso non è così:
Un'altra area in cui esistono variazioni è l'interpretazione degli indicatori di insensibilità al caso.
Un'altra risposta a Unicode è stata l'introduzione di classi di caratteri per i blocchi Unicode e le proprietà generali dei caratteri Unicode:
Appunti:
Esistono almeno tre famiglie di algoritmi che determinano se una stringa corrisponde a un'espressione regolare.
L'approccio più antico, chiamato esplicito, si basa sulla traduzione dell'espressione regolare in un automa finito deterministico (DFA). La costruzione di un tale automa per un'espressione regolare di dimensione m ha una complessità in dimensione e in memoria in O (2 m ) ma può essere eseguita su una stringa di dimensione n in un tempo O (n) .
Un approccio alternativo, detto implicito, consiste nel simulare un automa finito non deterministico costruendo al volo ogni AFD e sbarazzarsene nel passaggio successivo. Questo approccio evita la complessità esponenziale dell'approccio precedente, ma il tempo di esecuzione aumenta di O (mn) . Questi algoritmi sono veloci ma alcune funzionalità come la riacquisizione di sottostringhe e la quantizzazione non greedy sono difficili da implementare.
Il terzo approccio consiste nel confrontare il pattern con la stringa di caratteri mediante separazione e valutazione (" backtracking "). La sua complessità algoritmica è esponenziale nel peggiore dei casi, ad esempio con pattern come (a|aa)*b, ma nella pratica dà buoni risultati. È più flessibile e consente una maggiore potenza espressiva, ad esempio semplificando la ricattura delle sottostringhe.
Alcune implementazioni tentano di combinare le qualità di diversi approcci, iniziando la ricerca con un AFD, quindi utilizzando la separazione e la valutazione quando necessario.