Как удалить несколько (необязательных) частей строки SQL с помощью регулярных выражений .NET? - PullRequest
0 голосов
/ 22 апреля 2010

Я работаю над этим уже несколько часов и не могу найти никакой помощи по этому вопросу.По сути, я пытаюсь разбить строку SQL на различные части (поля, откуда, где, groupBy, orderBy).Я отказываюсь верить, что я первый человек, который когда-либо пытался сделать это, поэтому я хотел бы попросить совета от сообщества StackOverflow.:)

Чтобы понять, что мне нужно, предположим следующую строку SQL:

select * from table1 inner join table2 on table1.id = table2.id 
where field1 = 'sam' having table1.field3 > 0 
group by table1.field4 order by table1.field5 

Я создал регулярное выражение для соответствующей группировки частей:

select\s+(?<fields>.+)\s+from\s+(?<from>.+)\s+where\s+(?<where>.+)\s+having\s+(?<having>.+)\s+group\sby\s+(?<groupby>.+)\s+order\sby\s+(?<orderby>.+)

Этодает мне следующие результаты:

fields => *
from => table1 inner join table2 on table1.id = table2.id
where => field1 = 'sam'
having => table1.field3 > 0
groupby => table1.field4
orderby => table1.field5 

Проблема, с которой я столкнулся, заключается в том, что если любая часть строки SQL отсутствует после предложения 'from', регулярное выражениене совпадает

Чтобы исправить это, я попытался поместить каждую необязательную деталь в отдельную группу (...)?, но это не работает.Он просто помещает все необязательные части (где, имея, groupBy и orderBy) в группу «из».

Есть идеи?

1 Ответ

2 голосов
/ 22 апреля 2010

Невозможно сделать это идеально, используя регулярные выражения .Net;вам нужен стековый парсер.

Если вы не понимаете почему, рассмотрите следующие два допустимых запроса:

SELECT 'I\'m from Kansas', 'where the grass is greener'     
FROM Minnesota 
WHERE Grass = 'Blue'

SELECT 
    ID,
    Name IN (SELECT Name From Employees WHERE Rank > 4),
    Grade
FROM Employees
WHERE Rank < 4

РЕДАКТИРОВАТЬ

Чтобы ответить на вопрос:

new Regex(@"

    ^
    select\s+(?<fields>.+?)
        \s+ from       \s+ (?<from>    .+?)
    (?: \s+ where      \s+ (?<where>   .+?))?
    (?: \s+ having     \s+ (?<having>  .+?))?
    (?: \s+ group\s+by \s+ (?<groupby> .+?))?
    (?: \s+ order\s+by \s+ (?<orderby> .+ ))?
    $", 

        RegexOptions.IgnoreCase | RegexOptions.IgnorePatternWhitespace);

(перепроверено)
Это не будет обрабатывать вложенные запросы или строковые литералы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...