Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / WinForms, .Net Framework Новый топик    Ответить
 регулярные выражения для разбора sql запроса  [new]
Kometulus
Member

Откуда:
Сообщений: 3
Привет всем, кто это читает
Пытаюсь разобраться в написании регулярного выражения для разбора sql запроса следующего вида:
Select field1, field2 … from table1 where field1 < 5

Есть список требований:
- Количество полей может быть перечислено сколько угодно.
- После последнего поля нету символа «,»
- Таблица может быть только одна
- Возможны только знаки сравнения <>,<,>,<=,>=,=
- Сравнение выполняется только с целыми числами
- Между словами и знаками может быть сколько угодно пробелов, в соответствии с синтаксисом sql.

Что-то ничего не выходит, кто-нибудь знает как это делается?
30 май 21, 16:08    [22328985]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
fkfka
Member

Откуда:
Сообщений: 131
Тут есть один мембер, который эксперт в регулярках, давно, правда, его что-то не видно. Он даже писал на регулярках транспиллеры из перла с сиплюсплюс и т.п.

Если серьёзно, то область всей теории регулярных языков и, соответственно, регулярных выражений это только лексический разбор текста. Весь запрос ты этим не разберешь, потому что это уже синтаксический разбор, который выходит за рамки регулярщины.
30 май 21, 16:36    [22328989]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
если речь про MSSQL, то есть такая сборка Microsoft.SqlServer.Management.SqlParser.dll, она входит в SSMS и в VS, возможно распространяется с каким то бесплатным пакетом для Windows, ищите и обрящете. Я взял тот, что из папки с SSMS

В результате вызова получим довольно сложный объект, я не разбирался, что да как в нем, оставляю это вам. Но там есть свойство
result.Script.Xml, которую можно к примеру открыть в XmlDocument, но думаю лучше разобраться в кишках самого объекта, там всё есть
Как это лицензировать я не знаю, можно ли делать такое, вопрос... Но как мне кажется, если у вас есть на компе такая сборка, значит можно :) почему нет. И скорее всего её можно возить с собой, нужно только разобраться с зависимостями

у меня файлы были вот тут:
C:\>dir Microsoft.SqlServer.Management.SqlParser.dll /s /b /a
C:\Program Files (x86)\Microsoft SQL Server Management Studio 18\
Common7\IDE\Microsoft.SqlServer.Management.SqlParser.dll
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\SQLCommon\
130\Microsoft.SqlServer.Management.SqlParser.dll
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\SQLCommon\
140\Microsoft.SqlServer.Management.SqlParser.dll
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\Common7\IDE\Extensions\Microsoft\SQLCommon\
150\Microsoft.SqlServer.Management.SqlParser.dll

using System;
using Microsoft.SqlServer.Management.SqlParser.Parser;

namespace ExampleConsoleProject
{
    class Program
    {
        static void Main(string[] args)
        {
            var result = Parser.Parse("SELECT A,B,C FROM TABLE1 WHERE A = 1");
            Console.WriteLine(result.Script.Xml);
            Console.ReadKey();
        }
    }
}




<SqlSelectStatement Location="((1,1),(1,37))">
  <!--SELECT A,B,C FROM TABLE1 WHERE A = 1-->
  <SqlSelectSpecification Location="((1,1),(1,37))">
    <!--SELECT A,B,C FROM TABLE1 WHERE A = 1-->
    <SqlQuerySpecification Location="((1,1),(1,37))">
      <!--SELECT A,B,C FROM TABLE1 WHERE A = 1-->
      <SqlSelectClause Location="((1,1),(1,13))" IsDistinct="False">
        <!--SELECT A,B,C-->
        <SqlSelectScalarExpression Location="((1,8),(1,9))">
          <!--A-->
          <SqlColumnRefExpression Location="((1,8),(1,9))" ColumnName="A" MultipartIdentifier="A">
            <!--A-->
            <SqlObjectIdentifier Location="((1,8),(1,9))" ObjectName="A">
              <!--A-->
              <SqlIdentifier Location="((1,8),(1,9))" Value="A">
                <!--A-->
              </SqlIdentifier>
            </SqlObjectIdentifier>
          </SqlColumnRefExpression>
        </SqlSelectScalarExpression>
        <SqlSelectScalarExpression Location="((1,10),(1,11))">
          <!--B-->
          <SqlColumnRefExpression Location="((1,10),(1,11))" ColumnName="B" MultipartIdentifier="B">
            <!--B-->
            <SqlObjectIdentifier Location="((1,10),(1,11))" ObjectName="B">
              <!--B-->
              <SqlIdentifier Location="((1,10),(1,11))" Value="B">
                <!--B-->
              </SqlIdentifier>
            </SqlObjectIdentifier>
          </SqlColumnRefExpression>
        </SqlSelectScalarExpression>
        <SqlSelectScalarExpression Location="((1,12),(1,13))">
          <!--C-->
          <SqlColumnRefExpression Location="((1,12),(1,13))" ColumnName="C" MultipartIdentifier="C">
            <!--C-->
            <SqlObjectIdentifier Location="((1,12),(1,13))" ObjectName="C">
              <!--C-->
              <SqlIdentifier Location="((1,12),(1,13))" Value="C">
                <!--C-->
              </SqlIdentifier>
            </SqlObjectIdentifier>
          </SqlColumnRefExpression>
        </SqlSelectScalarExpression>
      </SqlSelectClause>
      <SqlFromClause Location="((1,14),(1,25))">
        <!--FROM TABLE1-->
        <SqlTableRefExpression Location="((1,19),(1,25))" ObjectIdentifier="TABLE1">
          <!--TABLE1-->
          <SqlObjectIdentifier Location="((1,19),(1,25))" ObjectName="TABLE1">
            <!--TABLE1-->
            <SqlIdentifier Location="((1,19),(1,25))" Value="TABLE1">
              <!--TABLE1-->
            </SqlIdentifier>
          </SqlObjectIdentifier>
        </SqlTableRefExpression>
      </SqlFromClause>
      <SqlWhereClause Location="((1,26),(1,37))">
        <!--WHERE A = 1-->
        <SqlComparisonBooleanExpression Location="((1,32),(1,37))" ComparisonOperator="Equals">
          <!--A = 1-->
          <SqlColumnRefExpression Location="((1,32),(1,33))" ColumnName="A" MultipartIdentifier="A">
            <!--A-->
            <SqlObjectIdentifier Location="((1,32),(1,33))" ObjectName="A">
              <!--A-->
              <SqlIdentifier Location="((1,32),(1,33))" Value="A">
                <!--A-->
              </SqlIdentifier>
            </SqlObjectIdentifier>
          </SqlColumnRefExpression>
          <SqlLiteralExpression Location="((1,36),(1,37))" Value="1" Type="Integer">
            <!--1-->
          </SqlLiteralExpression>
        </SqlComparisonBooleanExpression>
      </SqlWhereClause>
    </SqlQuerySpecification>
  </SqlSelectSpecification>
</SqlSelectStatement>


Сообщение было отредактировано: 30 май 21, 17:49
30 май 21, 17:50    [22329004]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
.

Сообщение было отредактировано: 30 май 21, 17:45
30 май 21, 17:53    [22329005]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
hVostt
Member

Откуда:
Сообщений: 19326
Kometulus
Что-то ничего не выходит, кто-нибудь знает как это делается?


Если не секрет, цель данного упражнения?
30 май 21, 22:17    [22329037]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
fkfka
Member

Откуда:
Сообщений: 131
hVostt
Если не секрет, цель данного упражнения?

Вестимо, запись "зачет" в зачетке. Если особо поразить преподавателя, то он, может быть, напишет: "Автор - адский сатана", но я такого еще не видел.
30 май 21, 22:59    [22329046]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
hVostt
Member

Откуда:
Сообщений: 19326
fkfka
hVostt
Если не секрет, цель данного упражнения?

Вестимо, запись "зачет" в зачетке. Если особо поразить преподавателя, то он, может быть, напишет: "Автор - адский сатана", но я такого еще не видел.


Ну судя по требованию сделать это на регулярках и ограничениях, это точно не практическая задача.

Особо понравилось:

Kometulus
Пытаюсь разобраться в написании...


и

Kometulus
Что-то ничего не выходит


:)

Т.е. по сути все "попытки" ограничились рассылкой на разные площадки и форумы.
31 май 21, 00:10    [22329059]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Сон Веры Павловны
Member

Откуда:
Сообщений: 6192
Kometulus,

Контекстно-зависимые грамматики алгоритмами, основанными на конечных автоматах, не разбираются. Просто примите это как аксиому. Даже попытка написать на регулярках парсер html или xml обречена на провал. Здесь можно использовать какие-нить паттерны типа визитор, ANTLR, ещё что-то, но не регулярки.
Есть вот такой легендарный пост на SoF - к парсингу SQL регулярками он относится в ещё большей степени.

Сообщение было отредактировано: 31 май 21, 06:28
31 май 21, 06:36    [22329087]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Изопропил
Member

Откуда:
Сообщений: 31571
Сон Веры Павловны
Контекстно-зависимые грамматики алгоритмами, основанными на конечных автоматах, не разбираются.

Контестно-свободные тоже
31 май 21, 13:08    [22329284]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
fkfka
Member

Откуда:
Сообщений: 131
Roman Mejtes,

Настоящим разбором SQL-выражения занимается сервер БД. Если что-то входит просто в SSMS, то это, скорее всего, что-то для подсветки синтаксиса, м.б. интеллисенса, и т.п.
31 май 21, 13:14    [22329288]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Roman Mejtes
Member

Откуда: г. Пермь
Сообщений: 4207
fkfka,

какая разница? конкретную задачу автора данная либа решает. можно посмотреть все столбцы, таблицы, учесть union'ы, не знаю как там с view'ами и т.д. Надо просто пробовать, сам не юзал, но судя по XML вся инфа есть. Есть даже знакоместа.
31 май 21, 14:08    [22329329]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
fkfka
Member

Откуда:
Сообщений: 131
Roman Mejtes
какая разница? конкретную задачу автора данная либа решает.

Так-то да, я согласен.
31 май 21, 14:14    [22329335]     Ответить | Цитировать Сообщить модератору
 Re: регулярные выражения для разбора sql запроса  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4155
hVostt
fkfka
пропущено...

Вестимо, запись "зачет" в зачетке. Если особо поразить преподавателя, то он, может быть, напишет: "Автор - адский сатана", но я такого еще не видел.


Ну судя по требованию сделать это на регулярках и ограничениях, это точно не практическая задача.

Особо понравилось:

Kometulus
Пытаюсь разобраться в написании...


и

Kometulus
Что-то ничего не выходит


:)

Т.е. по сути все "попытки" ограничились рассылкой на разные площадки и форумы.


"регулярные выражения" - это вершина для преподавателя и студента того заведения.
Последнее пристанище. А вот то, о чем написал юзер, что некоторые грамматики не разбираются при помощи рв - это уже за гранью добра и зла для них.
2 июн 21, 12:30    [22330256]     Ответить | Цитировать Сообщить модератору
Все форумы / WinForms, .Net Framework Ответить