Как выделить ключевые слова SQL с помощью регулярного выражения?

голоса
31

Я хотел бы выделить ключевые слова SQL, которые встречаются внутри строки в синтаксическом подсветке. Вот правила, которые я хотел бы иметь:

  • Сравните ключевые слова SELECT и FROM (другие будут добавлены, но мы начнем здесь). Должно быть, все колпачки
  • Должно содержаться в строке -- либо начинающейся с, 'либо
  • Первое слово в этой строке (игнорируя предшествующие ему пробелы) должно быть одним из ключевых слов.

Это, конечно, не исчерпывающе (можно не обращать внимания на побеги внутри строки), но я хотел бы начать с этого.

Вот несколько примеров:

  • SELECT * FROM main -- не будет совпадать (не в строке)
  • SELECT name FROM main -- будет соответствовать

  • ВЫБЕРИТЕ имя из основного -- будет соответствовать
  • Вот SQL-оператор:

SELECT * FROM main -- Нет, строка не начинается с ключевого слова (SELECT...).

Я думал, что единственный способ сделать это в одном регексе - это отрицательный взгляд... но тогда не будет фиксированной ширины, так как мы не знаем, когда начинается строка. Что-то вроде..:

Но это, конечно, не сработает:

enter

Можно ли сделать что-то подобное в одном регексе?

Задан 25/05/2020 в 00:37
источник пользователем
На других языках...                            


3 ответов

голоса
0

Подходящее регулярное выражение, скорее всего, будет довольно сложным, особенно по мере дальнейшего развития правил. Как отмечали другие, возможно, стоит подумать об использовании парсера. Тем не менее, вот один возможный регекс, пытающийся охватить упомянутые до сих пор правила:

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

Regular expression visualization

Демонстрационные онлайн-версии

  1. Демонстрация Debuggex
  2. Regex101 Демонстрация

Пояснение

Как видно из приведенной выше визуализации, регекс ищет либо двойную, либо одиночную кавычку в начале (сохраненную в захвате группы #1), а затем совпадает с этой ссылкой в конце через \1. SELECTИ FROMключевые слова записываются в захватывающих группах #2 и #3. (?:(x|y)Синтаксис гарантирует, что не будет больше групп для других вариантов, так ?:как в начале выбор исключает его как захватывающую группу. ) Есть некоторые дополнительные дополнительные детали, такие как ограничение того, что разрешено между SELECTи FROMне считая окончательной кавычки, если она немедленно сменяется символом слова.

Результаты

id="до 0"
Ответил 31/05/2020 в 13:55
источник пользователем

голоса
0

Вы можете использовать захват групп:

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

В этом случае 2 доллара относятся к первому ключевому слову, а 3 доллара - ко второму. Это также работает, если есть только два ключевых слова и только одна строка в строке, что кажется верным во всех ваших примерах, но если эти ограничения не работают для вас, дайте мне знать.

Ответил 28/05/2020 в 19:39
источник пользователем

голоса
0

Только что протестировал регеxp:

enter image description here

Если Вам нужно добавить другие команды, то это может привести к небольшому подвоху, потому что некоторые ключевые слова не применяются. Eg: ALTER TABLE mytable или UPDATE SET col = val;. Для этих сценариев Вам нужно будет создать подгруппы, и регеxp может стать медленным.

С наилучшими пожеланиями!

Ответил 28/05/2020 в 21:19
источник пользователем

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