MySQL Espressioni regolari (Regexp)
⚡ Riepilogo intelligente
MySQL Le espressioni regolari (REGEXP) confrontano i valori delle colonne con modelli flessibili che i caratteri jolly non possono esprimere. Questo spiega la sintassi REGEXP, il sinonimo RLIKE, ogni metacarattere supportato, esempi di query corretti sul database myflixdb e le funzioni di espressione regolare aggiunte in MySQL 8.0

Che cosa sono MySQL espressioni regolari?
MySQL espressioni regolari Ti aiutano a cercare dati che corrispondono a criteri complessi. Un'espressione regolare è un modello che descrive la forma del valore che stai cercando, piuttosto che il valore stesso.
Se hai già lavorato con MySQL jollyPotresti chiederti perché valga la pena imparare le espressioni regolari quando LIKE produce risultati simili. La risposta sta nella potenza espressiva: i caratteri jolly offrono solo due simboli, mentre le espressioni regolari descrivono intervalli di caratteri, alternative, ripetizioni e posizioni delle parole in un unico schema.
Una volta chiarito lo scopo, la sezione successiva introduce la sintassi che utilizzerete in ogni query REGEXP.
Sintassi di base delle espressioni regolari (REGEXP)
La sintassi di base per un'espressione regolare è la seguente.
SELECT * FROM table_name WHERE fieldname REGEXP 'pattern';
QUI:
- "Istruzione SELECT" è lo standard Istruzione SELECT.
- “DOVE nome campo” è il nome della colonna su cui viene eseguita l'espressione regolare.
- “Modello REGEXP”” — REGEXP è l'operatore di espressione regolare e 'pattern' rappresenta il modello da confrontare. RLIKE è un sinonimo di REGEXP e restituisce gli stessi risultati. Per evitare di confonderlo con l'operatore LIKE, è meglio usare REGEXP.
Vediamo ora un esempio pratico.
SELECT * FROM `movies` WHERE `title` REGEXP 'code';
La query sopra riportata cerca tutti i titoli dei film che contengono la parola "code". Non importa se "code" compare all'inizio, al centro o alla fine del titolo. Finché il titolo contiene il pattern, viene restituita la riga.
Corrispondenza tra l'inizio di un valore e un elenco di caratteri
Supponiamo di voler selezionare i film i cui titoli iniziano con le lettere a, b, c o d, seguite da un numero qualsiasi di altri caratteri. Per ottenere questo risultato, combiniamo un elenco di caratteri con il metacarattere accento circonflesso.
SELECT * FROM `movies` WHERE `title` REGEXP '^[abcd]';
Eseguendo lo script precedente in MySQL banco di lavoro Il confronto con il database myflixdb ci fornisce i seguenti risultati.
| id_film | titolo | direttore | anno_rilasciato | categoria_id |
|---|---|---|---|---|
| 4 | Code Nome Nero | Edgar Jimz | 2010 | NULL |
| 5 | Le bambine di papà | NULL | 2007 | 8 |
| 6 | Angeli e Demoni | NULL | 2007 | 6 |
| 7 | Da Vinci Code | NULL | 2007 | 6 |
Nel modello '^[abcd]', l'accento circonflesso (^) richiede che la corrispondenza inizi dall'inizio del valore e l'elenco di caratteri [abcd] accetta solo titoli la cui prima lettera è a, b, c o d. Il confronto non è sensibile alle maiuscole/minuscole con la collazione predefinita, motivo per cui "Code Viene restituito il nome "Black".
Escludendo i personaggi con un elenco di personaggi negati
Modifichiamo ora lo script e invertiamo l'ordine dei caratteri nell'elenco per vedere quali righe vengono restituite.
SELECT * FROM `movies` WHERE `title` REGEXP '^[^abcd]';
Eseguendo lo script precedente in MySQL L'analisi con Workbench sul database myflixdb ci fornisce i seguenti risultati.
| id_film | titolo | direttore | anno_rilasciato | categoria_id |
|---|---|---|---|---|
| 1 | Pirati dei Caraibi 4 | Rob Marshall | 2011 | 1 |
| 2 | Dimenticando Sarah Marshal | Nicholas Stoller | 2008 | 2 |
| 3 | X-Men | 2008 | ||
| 9 | Honey moonERS | John Schutz | 2005 | 8 |
| 16 | 67% colpevole | 2012 | ||
| 17 | Il grande dittatore | Chalie Chalie | 1920 | 7 |
| 18 | filmato di esempio | Anonimo | 8 | |
| 19 | film 3 | John Brown | 1920 | 8 |
All'interno di un elenco di caratteri, il significato del simbolo di accento circonflesso cambia: '^[^abcd]' continua ad ancorare la corrispondenza all'inizio, mentre [^abcd] ora esclude ogni titolo che inizia con uno dei caratteri racchiusi tra parentesi.
Questi due esempi utilizzano solo ancore ed elenchi di personaggi. La sezione successiva illustra l'insieme completo dei metacaratteri.
Metacaratteri delle espressioni regolari
Gli esempi sopra riportati mostrano la forma più semplice di un'espressione regolare. I metacaratteri consentono di perfezionare una ricerca di pattern: esprimono ripetizioni, alternative, intervalli e posizioni. La tabella seguente elenca tutti i metacaratteri supportati da MySQL Operatore REGEX, con un esempio corretto per ciascuno.
| carbonizzare | Descrizione | Esempio | |
|---|---|---|---|
| * | Migliori asterisco (*) corrisponde a zero (0) o più istanze del singolo carattere che lo precede. | SELEZIONA * DA film DOVE titolo REGEXP 'da*'; corrisponde a una “d” seguita da zero o più caratteri “a”, quindi Da Vinci Code e Daddy's Little Girls sono qualificate. Usa 'da+' quando la lettera 'a' deve essere effettivamente presente. | |
| + | Migliori più (+) corrisponde a una o più occorrenze del carattere che lo precede. | SELEZIONA * DA `film` DOVE `titolo` REGEXP 'mon+'; Restituisce tutti i film che contengono “mon” seguito da una o più lettere “n”. Ad esempio, Angeli e Demoni. | |
| ? | Migliori punto interrogativo (?) corrisponde a zero (0) o a una sola occorrenza del carattere che lo precede. | SELECT * FROM `categories` WHERE `category_name` REGEXP 'com?'; Corrisponde a “co” con una “m” facoltativa. Ad esempio, comedy e romantic comedy. | |
| . | Migliori punto (.) corrisponde a qualsiasi singolo carattere tranne un'interruzione di riga. | SELEZIONA * DA film DOVE `anno_pubblicato` REGEXP '200.'; Elenca tutti i film usciti in un anno che inizia con "200" seguito da un singolo carattere. Ad esempio, 2005, 2007, 2008. | |
| [ABC] | Migliori elenco dei caratteri [abc] corrisponde a uno qualsiasi dei caratteri racchiusi. | SELEZIONA * FROM `film` DOVE `titolo` REGEXP '[vwxyz]'; indica tutti i film che contengono un singolo personaggio di "vwxyz". Ad esempio, X-Men e Da Vinci Code. | |
| [^abc] | Migliori lista negata [^abc] corrisponde a qualsiasi carattere tranne quelli racchiusi tra parentesi. | SELECT * FROM `film` WHERE `titolo` REGEXP '^[^vwxyz]'; Fornisce tutti i film il cui titolo non inizia con un carattere di “vwxyz”. | |
| [AZ] | Migliori intervallo [AZ] corrisponde a qualsiasi lettera maiuscola. | SELECT * FROM `membri` WHERE `indirizzo_postale` REGEXP '[AZ]'; Fornisce l'elenco di tutti i membri il cui indirizzo postale contiene una lettera compresa tra la A e la Z. Ad esempio, Janet Jones con il numero di iscrizione 1. | |
| [az] | Migliori intervallo [az] corrisponde a qualsiasi lettera minuscola. | SELECT * FROM `membri` WHERE `indirizzo_postale` REGEXP '[az]'; Restituisce tutti i membri il cui indirizzo postale contiene una lettera compresa tra la a e la z. Si noti che la collazione predefinita non distingue tra maiuscole e minuscole, quindi questo intervallo corrisponde anche alle lettere maiuscole. | |
| [0-9] | Migliori intervallo [0-9] corrisponde a qualsiasi cifra da 0 a 9. | SELECT * FROM `members` WHERE `contact_number` REGEXP '[0-9]'; Fornisce tutti i membri il cui numero di telefono contiene almeno una cifra. Ad esempio, Robert Phil. | |
| ^ | Migliori accento circonflesso (^) ancora la corrispondenza all'inizio del valore. | SELECT * FROM `film` WHERE `titolo` REGEXP '^[cd]'; restituisce tutti i film il cui titolo inizia con “c” o “d”. Ad esempio, Code Name Black, Daddy's Little Girls e Da Vinci Code. | |
| $ | Migliori simbolo del dollaro ($) ancora la corrispondenza alla fine del valore. | SELECT * FROM `movies` WHERE `title` REGEXP 'code$'; elenca tutti i film il cui titolo termina con “code”. Ad esempio, Davinci Code. | |
| | | Migliori barra verticale (|) isola le alternative. | SELECT * FROM `film` WHERE `titolo` REGEXP '^[cd]|^[u]'; restituisce tutti i film il cui titolo inizia con “c”, “d” o “u”. Ad esempio, Code Nome Nero, Da Vinci Codee mondo sotterraneo – AwakenING. | |
| \b | Migliori confine di parola (\b) corrisponde all'inizio o alla fine di una parola. Sostituisce i vecchi marcatori [[:<:]] e [[:>:]], che MySQL 8.0 rimosso. | SELECT * FROM `movies` WHERE `title` REGEXP '\\bfor'; dà tutti i film con una parola che inizia con “for”. Ad esempio, Forgetting Sarah Marshal. MySQL 5.7 il modello equivalente è '[[:<:]]for'. | |
| [[:classe:]] | Migliori classe di caratteri corrisponde a un gruppo di caratteri denominato: [[:alpha:]] per le lettere, [[:space:]] per gli spazi bianchi, [[:punct:]] per la punteggiatura e [[:upper:]] per le lettere maiuscole. Nota il doppio parentesi quadre. | SELECT * FROM `movies` WHERE `title` REGEXP '^[[:alpha:][:space:]]+$'; restituisce tutti i film il cui titolo contiene solo lettere e spazi. Ad esempio, Forgetting Sarah Marshall, mentre Pirates of the Caribbean 4 viene omesso a causa della cifra. | |
La barra rovesciata (\) è il carattere di escape. Perché MySQL analizza prima la stringa e poi il pattern; una barra rovesciata letterale deve essere scritta come una doppia barra rovesciata (\\) all'interno di un pattern REGEXP.
⚠️ Avviso sulla versione: MySQL 8.0.4 ha sostituito il vecchio motore di espressioni regolari con la libreria ICU. I marcatori di parole [[:<:]] e [[:>:]] sono stati rimossi in quella versione, quindi i modelli copiati da materiale precedente falliscono con un "errore di sintassi" su MySQL 8.0. Utilizzare \b al posto di \b.
Ora che tutti i metacaratteri sono stati definiti, sorge spontanea una domanda: quando le espressioni regolari (REGEXP) dovrebbero sostituire il più semplice operatore LIKE?
REGEXP o LIKE: quale utilizzare?
Entrambi gli operatori filtrano le righe in base a un modello, ma risolvono problemi diversi. LIKE comprende solo due simboli, mentre REGEXP comprende l'intero set di metacaratteri mostrato sopra. Questa maggiore potenza ha un costo, quindi la scelta è un compromesso piuttosto che una preferenza.
| Criterio | COME | REGEXP |
|---|---|---|
| marchi di protezione | % e _ soltanto | Anchors, intervalli, alternanza, quantificatori, classi di caratteri |
| Utilizzo tipico | Ricerche per prefisso, suffisso e “contiene” | Validazione, alternative multiple, corrispondenza basata sulla posizione |
| Utilizzo dell'indice | Possibile quando il modello non inizia con % | non utilizza mai un indice |
| Valore di ritorno | VERO o FALSO | 1 o 0, e NULL quando uno degli operandi è NULL |
Scegli LIKE per corrispondenze semplici, perché è di facile lettura e può comunque utilizzare un indice. Scegli REGEXP quando un singolo pattern deve esprimere più regole contemporaneamente, ad esempio "inizia con c o d e termina con una cifra". Su tabelle di grandi dimensioni, restringi prima le righe con una condizione indicizzata, quindi applica REGEXP al set più piccolo.
MySQL 8.0 Funzioni di espressione regolare
L'operatore REGEXP risponde a una sola domanda: il valore corrisponde al modello? MySQL 8.0 ha aggiunto quattro funzioni che vanno oltre e ti permettono di individuare, ad esempiotract, e riscrivi il testo corrispondente. Ciascuno accetta un argomento opzionale match_type, dove 'c' forza un confronto sensibile alle maiuscole e 'i' forza un confronto non sensibile alle maiuscole.
- REGEXP_LIKE(espressione, modello) Restituisce 1 quando il valore corrisponde al modello. È la forma funzionale dell'operatore REGEXP e l'argomento match_type rende esplicita la distinzione tra maiuscole e minuscole.
- REGEXP_INSTR(espressione, modello) Restituisce la posizione del primo carattere della corrispondenza, oppure 0 quando il modello non viene trovato.
- REGEXP_SUBSTR(espressione, modello) restituisce la sottostringa corrispondente, utile per estrarre un anno, un codice o un numero da un testo più lungo.
- REGEXP_REPLACE(espressione, modello, sostituzione) restituisce il valore con ogni corrispondenza sostituita, quindi può pulire i dati all'interno di un query di aggiornamento SQL.
SELECT title, REGEXP_SUBSTR(title, '[0-9]+') AS number_in_title FROM `movies` WHERE REGEXP_LIKE(title, '[0-9]');
La query sopra riporta tutti i titoli dei film che contengono una cifra, insieme alle cifre stesse. MySQL 5.7 Queste funzioni non sono disponibili, quindi l'operatore REGEXP rimane l'unica opzione.
