0

我正在为我的硕士论文开发一些应用程序,在此过程中我必须构建一个 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

对于第一部分和

(选择 s.RIC, m.NAME from Stock s, Market m where s.LISTED_ON_EXCHANGE=m.RIC) t

第二部分

4

1 回答 1

2
  • 字符类不是组——删除关键字周围的[& 。]
  • 不要使用无用的环视,在某些情况下会导致问题。
  • 您可能希望使用\baround 关键字,以便SELECTFOOSELECT.
  • 可以(?i)用来使表达式不区分大小写。

你可以使用类似的东西:

(?i)\bSELECT\b\s+(.+)\s+\bFROM\b\s+([\w\s,]+?)(?:\s+\b(?:WHERE|INNER|ORDER)\b|;?$)

在第一和第二捕获组中捕获感兴趣的部分。

请注意,这不适用于字符串,在其他情况下,SQL 也是递归的,这很难用 Java 正则表达式解析。如果您想正确解析 SQL,我建议您使用正确的解析器。(您可以自己编写一个简单的方法,使用正则表达式进行词法分析生成令牌,使用 Java 解析令牌并构建解析树。)

于 2012-06-20T11:43:26.977 回答