Wie hebt man SQL-Schlüsselwörter mit einem regulären Ausdruck hervor?

stimmen
31

Ich möchte SQL-Schlüsselwörter, die innerhalb einer Zeichenfolge vorkommen, in einem Syntax-Highlighter hervorheben. Hier sind die Regeln, die ich gerne hätte:

  • Ordnen Sie die Schlüsselwörter SELECT und FROM zu (weitere werden hinzugefügt, aber wir beginnen hier). Müssen Großbuchstaben sein
  • Muss in einer Zeichenkette enthalten sein -- entweder beginnend mit 'oder
  • Das erste Wort in dieser Zeichenfolge (unter Ignorierung des Leerzeichens davor) sollte eines der Schlüsselwörter sein.

Dies ist natürlich nicht umfassend (kann Ausbrüche innerhalb einer Zeichenfolge ignorieren), aber ich möchte hier beginnen.

Hier sind ein paar Beispiele:

  • SELECT * FROM main -- wird nicht übereinstimmen (nicht in einer Zeichenkette)
  • SELECT name FROM main -- wird übereinstimmen

  • SELECT name FROM main -- wird übereinstimmen
  • Hier ist eine SQL-Anweisung:

SELECT * FROM main -- nein, string beginnt nicht mit einem Schlüsselwort (SELECT...).

Die einzige Möglichkeit, die ich dachte, es in einem einzigen Regex zu tun, wäre mit einem negativen Blick dahinter... aber dann wäre es keine feste Breite, da wir nicht wissen, wann die Zeichenfolge beginnt. Etwas wie:

Aber das wird natürlich nicht funktionieren:

enter

Wäre es möglich, so etwas in einem einzigen Regex zu tun?

Veröffentlicht am 25/05/2020 um 00:37
quelle vom benutzer
In anderen Sprachen...                            


3 antworten

stimmen
0

Ein geeigneter regulärer Ausdruck wird wahrscheinlich ziemlich komplex werden, vor allem, wenn sich die Regeln weiter entwickeln. Wie andere bemerkt haben, könnte es sich lohnen, stattdessen einen Parser zu verwenden. Hier ist jedoch ein möglicher Regex, der versucht, die bisher erwähnten Regeln abzudecken:

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

Regular expression visualization

Online-Demos

  1. Debuggex-Demo
  2. Regex101-Demo

Erläuterung

Wie in der obigen Visualisierung zu sehen ist, sucht der Regex entweder nach einem doppelten oder einfachen Anführungszeichen am Anfang (gespeichert in der Erfassungsgruppe #1) und gleicht diese Referenz dann am Ende über \1. Die SELECTund FROMSchlüsselwörter werden in den Capturing-Gruppen #2 und #3 erfasst. (Die ?:(x|y)Syntax stellt sicher, dass es nicht mehr Gruppen für andere Auswahlmöglichkeiten gibt, da ?:am Anfang einer Auswahl diese als Erfassungsgruppe ausgeschlossen wird. ) Es gibt noch einige weitere optionale Details, wie z.B. die Einschränkung dessen, was zwischen dem SELECTund FROMerlaubt ist, und die Nichtberücksichtigung des letzten Anführungszeichens, wenn unmittelbar darauf ein Wortzeichen folgt.

Ergebnisse

id="vor 0"
Beantwortet am 31/05/2020 um 13:55
quelle vom benutzer

stimmen
0

Sie könnten Erfassungsgruppen verwenden:

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

In diesem Fall würde sich $2 auf das erste Schlüsselwort und $3 auf das zweite Schlüsselwort beziehen. Das funktioniert auch nur, wenn es nur zwei Schlüsselwörter und nur eine Zeichenfolge in einer Zeile gibt, was in allen Ihren Beispielen zutreffend zu sein scheint, aber wenn diese Einschränkungen für Sie nicht funktionieren, lassen Sie es mich wissen.

Beantwortet am 28/05/2020 um 19:39
quelle vom benutzer

stimmen
0

Habe gerade den regexp-Balg getestet:

enter image description here

Wenn Sie weitere Befehle hinzufügen müssen, kann die Sache ein kleiner Trick werden, weil einige Schlüsselwörter nicht zutreffen. Z.B.: ALTER TABLE mytable oder UPDATE SET col = val;. Für diese Szenarien müssen Sie Untergruppen erstellen, und der regexp kann langsam werden.

Beste Grüße!

Beantwortet am 28/05/2020 um 21:19
quelle vom benutzer

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