Come evidenziare le parole chiave SQL utilizzando un'espressione regolare?

voti
32

Vorrei evidenziare le parole chiave SQL che si verificano all'interno di una stringa in un evidenziatore di sintassi. Ecco le regole che vorrei avere:

  • Abbinare le parole chiave SELEZIONA e DA (altre verranno aggiunte, ma inizieremo da qui). Deve essere all-caps
  • Deve essere contenuto in una stringa - a partire da 'o
  • La prima parola in quella stringa (ignorando gli spazi bianchi che la precedono) dovrebbe essere una delle parole chiave.

Questo ovviamente non è esaustivo (può ignorare le fughe all'interno di una stringa), ma vorrei iniziare da qui.

Ecco alcuni esempi:

  • SELEZIONA * DA PRINCIPALE -- non corrisponde (non in una stringa)
  • SELEZIONA nome DA PRINCIPALE -- corrisponderà a

  • SELEZIONA nome DA PRINCIPALE -- corrisponderà
  • Ecco una frase SQL:

SELEZIONA * DALLA PRINCIPALE -- no, la stringa non inizia con una parola chiave (SELECT...).

L'unico modo in cui ho pensato di farlo in un singolo regex sarebbe stato con un lookbehind negativo... ma poi non sarebbe stata una larghezza fissa, perché non sappiamo quando inizia la stringa. Qualcosa del tipo:

Ma questo ovviamente non funzionerà:

enter

Sarebbe possibile fare qualcosa di simile in un unico regex?

È pubblicato 25/05/2020 alle 00:37
fonte dall'utente
In altre lingue...                            


3 risposte

voti
0

Un'espressione regolare adeguata può diventare piuttosto complessa, soprattutto se le regole si evolvono ulteriormente. Come altri hanno notato, potrebbe valere la pena di considerare l'uso di un parser. Detto questo, ecco un possibile tentativo di regex di coprire le regole menzionate finora:

(["'])\s*(SELECT)(?:\s+|\s.*\s)(FROM)(?:\s+.*)?\1(?:[^\w]|$)

Regular expression visualization

Demo online

  1. Demo Debuggex
  2. Regex101 Demo

Spiegazione

Come si può vedere nella visualizzazione di cui sopra, il regex cerca una citazione doppia o singola all'inizio (salvata nel gruppo di cattura n. 1) e poi corrisponde a questo riferimento alla fine tramite \1. Le parole chiave SELECTe le FROMparole chiave sono catturate nei gruppi di cattura #2 e #3. (La ?:(x|y)sintassi assicura che non ci siano più gruppi per altre scelte, poiché ?:all'inizio di una scelta la si esclude come gruppo di cattura. ) Ci sono alcuni ulteriori dettagli facoltativi, come la limitazione di ciò che è consentito tra la virgoletta SELECTe FROMla e senza contare la virgoletta finale se è immediatamente seguita da un carattere di parola.

Risultati

id="pre-0"
Risposto il 31/05/2020 a 13:55
fonte dall'utente

voti
0

Potreste usare i gruppi di cattura:

(.*["']\s*\K)(?(1)(SELECT|FROM).*(SELECT|FROM)|)

In questo caso 2 dollari si riferiscono alla prima parola chiave e 3 dollari alla seconda parola chiave. Questo funziona anche solo se ci sono solo due parole chiave e una sola stringa su una linea, il che sembra essere vero in tutti i vostri esempi, ma se queste restrizioni non funzionano per voi, fatemelo sapere.

Risposto il 28/05/2020 a 19:39
fonte dall'utente

voti
0

Ho appena testato il soffietto regexp:

enter image description here

Se avete bisogno di aggiungere altri comandi la cosa potrebbe ottenere un piccolo trucco, perché alcune parole chiave non si applicano. Ad esempio: ALTER TABLE mytable o UPDATE SET col = val;. Per questi scenari dovrete creare dei sottogruppi e il regexp potrebbe diventare lento.

Cordiali saluti!

Risposto il 28/05/2020 a 21:19
fonte dall'utente

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more