Jak zvýraznit klíčová slova SQL pomocí regulárního výrazu?

hlasů
31

Chtěl bych zdůraznit klíčová slova SQL, která se vyskytují v řetězci v zvýrazňovači syntaxe. Zde jsou pravidla, která bych chtěl mít:

  • Shoda klíčových slov SELECT a FROM (budou přidána další, ale začneme zde). Musí to být vše-cap
  • Musí být obsažena v řetězci - buď počínaje ' nebo
  • První slovo v tomto řetězci (ignorující mezeru předcházející mu) by mělo být jedno z klíčových slov.

To samozřejmě není komplexní (může ignorovat útěky v řetězci), ale rád bych začal zde.

Zde je několik příkladů:

  • SELECT * FROM main - nebude odpovídat (není v řetězci)
  • „SELECT jméno od hlavního“ - bude odpovídat
  • "
    VYBRAT název Z hlavního "- bude odpovídat
  • "" "Zde je příkaz SQL:

VÝBĚR * Z hlavního "" "- ne, řetězec nezačíná klíčovým slovem (VYBRAT ...).

Jediný způsob, jak jsem si myslel, že to udělám v jednom regexu, bude s negativním pohledem ... ale pak by to nebyla pevná šířka, protože nevíme, kdy začíná řetězec. Něco jako:

Ale to samozřejmě nebude fungovat:

zde

Bylo by možné něco takového udělat v jediném regexu?

Položena 25/05/2020 v 00:37
zdroj uživatelem
V jiných jazycích...                            


3 odpovědí

hlasů
0

Vhodný regulární výraz bude pravděpodobně docela složitý, zejména s tím, jak se pravidla dále vyvíjejí. Jak již uvedli ostatní, může být vhodné místo toho zvážit použití analyzátoru. To znamená, že zde je jeden možný regex, který se pokouší pokrýt výše uvedená pravidla:

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

Vizualizace regulárních výrazů

Ukázky online

  1. Debuggex Demo
  2. Ukázka Regex101

Vysvětlení

Jak je vidět na výše uvedené vizualizaci, regex hledá na začátku buď dvojitou nebo jednoduchou citaci (uloženou v zachycující skupině č. 1) a poté na konci porovnává tento odkaz prostřednictvím \1 . SELECT a FROM Klíčová slova jsou zachycena při zachycení skupin # 2 a # 3. (The ?:(x|y) syntaxe zajistí, že nebude existovat více skupin pro další volby jako ?: na začátku volby je vyloučí jako zachycující skupina.) Existují některé další volitelné podrobnosti, například omezení toho, co je povoleno mezi SELECT a FROM a nepočítat konečnou uvozovku, pokud je bezprostředně následováno znakem slova.

Výsledek

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
Odpovězeno 31/05/2020 v 13:55
zdroj uživatelem

hlasů
0

Mohli byste použít zachycující skupiny:

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

V tomto případě by 2 $ odkazovalo na první klíčové slovo a 3 $ odkazovalo na druhé klíčové slovo. To také funguje, pouze pokud jsou na řádku pouze dvě klíčová slova a pouze jeden řetězec, což se zdá být pravdivé ve všech vašich příkladech, ale pokud tato omezení pro vás nefungují, dejte mi vědět.

Odpovězeno 28/05/2020 v 19:39
zdroj uživatelem

hlasů
0

Právě testujeme regexp níže:

zde zadejte popis obrázku

Pokud potřebujete přidat další příkazy, může se to trochu zkusit, protože některá klíčová slova neplatí. Např .: ALTER TABLE mytable nebo UPDATE SET col = val ;. Pro tyto scénáře budete muset vytvořit podskupiny a regexp se může zpomalit.

S pozdravem!

Odpovězeno 28/05/2020 v 21:19
zdroj uživatelem

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