我正在为我的硕士论文开发一些应用程序,在此过程中我必须构建一个 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
第二部分
最佳答案
- 字符类不是组 - 删除关键字周围的
[
和]
。 - 不要使用无用的环视,这在某些情况下可能会导致问题。
- 您可能希望在关键字周围使用
\b
,以便SELECT
与FOOSELECT
中不匹配。 - 可以使用
(?i)
使表达式不区分大小写。
你可以使用类似的东西:
(?i)\bSELECT\b\s+(.+)\s+\bFROM\b\s+([\w\s,]+?)(?:\s+\b(?:WHERE|INNER|ORDER)\b|;?$)
在第一和第二捕获组中捕获感兴趣的部分。
请注意,这不适用于字符串,并且在其他情况下,SQL 也是递归的,这很难用 Java 正则表达式进行解析。如果你想正确解析 SQL,我建议你使用合适的解析器。 (您可以自己编写一个简单的,使用正则表达式来词法生成标记,并使用 Java 来解析标记并构建解析树。)
关于java - Select 子句复杂正则表达式模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11118655/