Comment mettre en évidence des mots-clés SQL en utilisant une expression régulière ?

voix
31

Je voudrais mettre en évidence les mots-clés SQL qui se trouvent dans une chaîne de caractères dans un surligneur syntaxique. Voici les règles que j'aimerais avoir :

  • Faites correspondre les mots clés SELECT et FROM (d'autres seront ajoutés, mais nous commencerons ici). Doit être all-caps
  • Doit être contenu dans une chaîne -- soit en commençant par 'ou
  • Le premier mot de cette chaîne (en ignorant les espaces qui la précèdent) doit être l'un des mots-clés.

Bien sûr, ce n'est pas exhaustif (on peut ignorer les échappements à l'intérieur d'une chaîne), mais j'aimerais commencer ici.

Voici quelques exemples :

  • SELECT * FROM main -- ne correspondra pas (pas dans une chaîne)
  • SÉLECTIONNER LE NOM DE LA PERSONNE PRINCIPALE -- correspondra

  • SÉLECTIONNER le nom de la personne principale -- correspondra
  • Voici une instruction SQL :

SELECT * FROM main -- non, la chaîne ne commence pas par un mot-clé (SELECT...).

La seule façon que j'ai pensé de le faire en une seule regex serait avec un regard négatif derrière... mais alors ce ne serait pas une largeur fixe, car on ne sait pas quand la chaîne commence. Quelque chose comme :

Mais bien sûr, cela ne fonctionnera pas :

enter

Serait-il possible de faire quelque chose comme cela dans une seule regex ?

Créé 25/05/2020 à 00:37
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
0

Une expression régulière appropriée est susceptible de devenir assez complexe, surtout si les règles évoluent encore. Comme d'autres l'ont fait remarquer, il peut être utile d'envisager d'utiliser un analyseur syntaxique à la place. Cela dit, voici une regex possible qui tente de couvrir les règles mentionnées jusqu'à présent :

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

Regular expression visualization

Démos en ligne

  1. Démonstration de Debuggex
  2. Démonstration de Regex101

Explication

Comme on peut le voir dans la visualisation ci-dessus, la regex recherche une citation double ou simple au début (enregistrée dans la capture du groupe #1) et fait ensuite correspondre cette référence à la fin via \1. Les FROMmots-clés SELECTet sont capturés dans les groupes de capture #2 et #3. (La ?:(x|y)syntaxe garantit qu'il n'y a pas plus de groupes pour les autres choix car ?:au début d'un choix, il est exclu en tant que groupe de capture. ) Il existe d'autres détails facultatifs tels que la limitation de ce qui est autorisé entre le SELECTet FROMet le fait de ne pas compter le guillemet final s'il est immédiatement suivi d'un caractère verbal.

Résultats

id="pre-0"
Créé 31/05/2020 à 13:55
source utilisateur

voix
0

Vous pourriez utiliser la capture de groupes :

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

Dans ce cas, 2 $ se rapportent au premier mot-clé et 3 $ au second. Cela ne fonctionne également que s'il n'y a que deux mots clés et une seule chaîne de caractères sur une ligne, ce qui semble être vrai dans tous vos exemples, mais si ces restrictions ne vous conviennent pas, faites-le moi savoir.

Créé 28/05/2020 à 19:39
source utilisateur

voix
0

Je viens de tester le soufflet regexp :

enter image description here

Si vous avez besoin d'ajouter d'autres commandes, le truc peut devenir un peu compliqué, car certains mots-clés ne s'appliquent pas. Ex : ALTER TABLE mytable ou UPDATE SET col = val ;. Pour ces scénarios, vous devrez créer des sous-groupes et la regexp peut devenir lente.

Meilleures salutations !

Créé 28/05/2020 à 21:19
source utilisateur

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