Hogyan lehet kiemelni az SQL kulcsszavakat egy reguláris kifejezés használatával?

szavazat
31

Szeretném kiemelni az SQL kulcsszavakat, amelyek a szintaxis kiemelőjében található karakterláncon belül fordulnak elő. A következő szabályokat szeretném betartani:

  • Egyeztesse a SELECT és FROM kulcsszavakat (mások hozzáadódnak, de itt kezdjük). Mindenképp nagynak kell lennie
  • A karakterláncban kell lennie - akár kezdődik ' vagy
  • A karakterláncban szereplő első szónak (figyelmen kívül hagyva az előtte lévő szóközt) az egyik kulcsszónak kell lennie.

Ez természetesen nem teljes (nem veheti figyelembe a karakterláncon belüli meneküléseket), de itt szeretnék kezdeni.

Íme néhány példa:

  • KIVÁLASZT * FŐRŐL - nem egyezik (nem karakterláncban)
  • " SELECT name FROM main" - megegyezik
  • "
    SELECT name FROM main "- megegyezik
  • "" "Itt egy SQL utasítás:

KIVÁLASZT * A fő "" "-ból - nem, a karakterlánc nem kezdődik kulcsszóval (KIVÁLASZTÁS ...).

Csak úgy gondoltam, hogy egyetlen regexben ezt megteszem, negatív hátsó nézettel ... de akkor nem lesz rögzített szélessége, mivel nem tudjuk, mikor kezdődik a húr. Valami hasonló:

De ez természetesen nem fog működni:

írja

Valami ilyesmit lehet megtenni egyetlen regexben?

A kérdést 25/05/2020 00:37
a forrás felhasználó
Más nyelveken...                            


3 válasz

szavazat
0

A megfelelő reguláris kifejezés valószínűleg meglehetősen összetett lesz, főleg a szabályok tovább fejlődésével. Mint mások megjegyezték, érdemes lehet fontolóra venni egy elemző használatát. Ennek ellenére itt van egy lehetséges regex, amely megpróbálja fedezni az eddig említett szabályokat:

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

Rendszeres kifejezés-megjelenítés

Online bemutató

  1. Debuggex Demo
  2. Regex101 Demo

Magyarázat

Amint az a fenti képi megjelenítésből kiderül, a regex az elején kettős vagy egyetlen idézetet keres (az 1. rögzítési csoportba mentve), majd a végén egyezteti ezt a referenciát a \1 . Az SELECT és FROM a kulcsszavakat a 2. és a 3. csoport rögzítésében rögzítik. (Az ?:(x|y) A szintaxis biztosítja, hogy ne legyen több csoport más választáshoz ?: a választás elején kizárja azt rögzítő csoportként.) Van néhány további választható részlet, például korlátozza a SELECT és FROM és nem számoljuk el a végső idézőjelet, ha azt egy szókarakter azonnal követi.

Eredmények

SELECT * FROM tbl        -- no match - not in a string
"SELECT * FROM tbl"      -- matches - in a double-quoted string
'SELECT * FROM tbl;'     -- matches - in a single-quoted string
'SELECT * FROM it's      -- no match - letter after end quote
"SELECT * FROM tbl'      -- no match - quotation marks don't match
'SELECT * FROM tbl"      -- no match - quotation marks don't match
"select * from tbl"      -- no match - keywords not upper case
'Select * From tbl'      -- no match - still not all upper case
"SELECT col1 FROM"       -- matches - even though no table name
'  SELECT  col1  FROM '  -- matches - as above with more whitespace
'SELECT col1, col2 FROM' -- matches - with multiple columns
Válaszolt 31/05/2020 13:55
a forrás felhasználó

szavazat
0

Használhatja a csoportok rögzítését:

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

Ebben az esetben a 2 dollár az első kulcsszóra, a 3 dollár a második kulcsszóra utalna. Ez csak akkor működik, ha csak két kulcsszó és csak egy karakterlánc van egy sorban, ami valószínűnek tűnik az összes példában, de ha ezek a korlátozások nem működnek érted, tudassa velem.

Válaszolt 28/05/2020 19:39
a forrás felhasználó

szavazat
0

Most teszteltem a regexp hangosbordáját:

írja ide a kép leírását

Ha további parancsokat kell hozzáadnia, a dolog kis trükköt kaphat, mert egyes kulcsszavak nem vonatkoznak. Pl .: ALTER TABLE mytable vagy UPDATE SET col = val ;. Ezekhez a forgatókönyvekhez alcsoportokat kell létrehozni, és a regexp lassú lehet.

Üdvözlettel!

Válaszolt 28/05/2020 21:19
a forrás felhasználó

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