【发布时间】:2012-06-20 11:34:59
【问题描述】:
我正在为我的硕士论文开发一些应用程序,在此过程中我必须构建一个 SQL 解析器。为此,我决定加强正则表达式,因为这似乎是当时最好的方法。
问题是我的正则表达式有一些小问题。
考虑一些查询示例,例如:
select
RIC
from
(select
s.RIC, m.NAME
from
Stock s, Market m
where
s.LISTED_ON_EXCHANGE = m.RIC) t
where
RIC > 'G';
select *
from Stock
order by COMPANY
LIMIT 0,2;
select 1+2;
select now();
select
s.RIC, m.NAME
from
Stock s
INNER JOIN
Market ON m I s.LISTED_ON_EXCHANGE = m.RIC;
select *
from Stock
order by COMPANY;
select *
from Stock
where RIC in ('GS.N' , 'INFY.BO');
select *
from Stock
where RIC LIKE 'V%';
select *
from Stock
where RIC BETWEEN 'G' AND 'I';
select count(*)
from STOCK
where LISTED_ON_EXCHANGE IS NOT NULL;
select na_me as n, price as p
from bla, blabla, blalalaa;
并给出以下两个正则表达式:
SELECT_FIELDS_PATTERN = "(?<=[SELECT]) [\\d\\w',.*() ]+ (?=FROM)";
这应该与选择字段匹配。
还有:
SELECT_FROM_PATTERN = "(?<=[FROM]) [\\w, ]+ (?(?=(?:WHERE|INNER|ORDER)))";
应该匹配 FROM 子句,不包括任何条件或排序等。
除
之外的所有查询select 1+2;
select now();
应该是有效的。那是因为我只想为我解析包含相关信息的选择查询。
问题是我创建的两个正则表达式不会验证例如最后一个查询:
select na_me as n, price as p from bla, blabla, blalalaa;
所以我需要一些帮助来改进我对选择查询的正则表达式,甚至可能合并两个正则表达式?
第一个查询的正确输出示例:
select RIC from (select s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t where RIC > 'G';
输出应该是:
RIC
第一部分和
(select s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t
第二部分
【问题讨论】:
-
如果练习本身不是关于解析器编写的,你不想使用像 antlr 和定义的 (sql) 语法这样的东西吗? antlr.org/grammar/list
-
@Glenn 我以前从未考虑过这个选项,但这确实会有所帮助
-
@Glenn 我不确定您是否可以使用 antlr 以类似 POJO 的格式提取数据。例如,我想有一个结构,例如:SelectDTO(根对象),它有一个 getFromClause()、getWhereClause() 等,例如,它们中的每一个也可以返回一个 SelectDTO,因为查询是递归的