选择子句复杂的正则表达式模式

时间:2012-06-20 11:34:59

标签: java sql regex

我正在为我的硕士论文申请一些申请,在这个过程中我必须建立一个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

第二部分

1 个答案:

答案 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解析令牌并构建解析树。)