我已经在这个工作了几个小时了,但却找不到任何帮助。基本上,我正在尝试将SQL字符串分成不同的部分(字段,from,where,having,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
我遇到的问题是,如果在'from'子句后缺少任何部分SQL字符串,则正则表达式不匹配。
为了解决这个问题,我尝试将每个可选部分放在它自己的(...)?
组中,但这不起作用。它只是将所有可选部分(where,having,groupBy和orderBy)放入'from'组。
有什么想法吗?
答案 0 :(得分:2)
使用.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);
(再测试)
这不会处理嵌套查询或字符串文字