我正在为我的硕士论文申请一些申请,在这个过程中我必须建立一个SQL Parser。为了做到这一点,我决定重新进行regexing,因为它似乎是当时最好的方式。
问题是我的正则表达式有一些小问题。
考虑一些查询示例,例如:
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
第一部分和
(选择s.RIC,来自Stock s的m.NAME,Market m,其中s.LISTED_ON_EXCHANGE = m.RIC)t
第二部分
答案 0 :(得分:2)
[
&amp; ]
围绕关键字。\b
,以便SELECT
中的FOOSELECT
不匹配。(?i)
使表达式不区分大小写。 您可以使用以下内容:
(?i)\bSELECT\b\s+(.+)\s+\bFROM\b\s+([\w\s,]+?)(?:\s+\b(?:WHERE|INNER|ORDER)\b|;?$)
在第一个和第二个捕获组中捕获感兴趣的部分。
注意这对字符串不起作用,而在其他情况下,SQL也是递归的,这很难用Java正则表达式解析。如果你想正确地解析SQL,我建议你使用一个合适的解析器。 (您可以自己编写一个简单的文件,使用正则表达式生成令牌,使用Java解析令牌并构建解析树。)