1

我正在使用 SQL 语法创建一个关系数据库,它将有一个使用 Java 的命令行界面。为了解析用户命令,我使用正则表达式(我知道这是一个糟糕的主意 - 学习比其他任何东西都多)
我使用带有分号作为分隔符的扫描仪类,所以我不寻找分号在我的正则表达式中。这样它就可以处理多行输入。输入在与正则表达式匹配之前被修剪,因此字符串开头和结尾的空格不是表达式的一部分。

我在这里有这个正则表达式,它按照我想要的方式工作,直到我为 where 子句添加可选标志 -

select\s+(.*?)(?:\s+where(.*))

那将匹配(组以粗体显示)-

从 *中选择一个x = 3

但是,如果我将正则表达式更改为此-

select\s+(.*?)(?:\s+where(.*))?

它只匹配引用的部分 -

"select "a from * where x = 3

我的目标是让它匹配所有内容,直到单词“select”(包括空格字符)之后的字符串结尾,除非前面和后面有一个字符串“where”和任何空格字符。如果存在,则将单词“select”和“where”之间的每个字符分组,并将所有单词分组在“where”之后。

例如:如果输入了此文本:

select a from * where b = 3

它应该将“ a from * ”和“ b = 3 ”组合在一起。

但如果这是输入:

select a where x = 3

表名“a”应该是一个组,where 子句“x = 3”应该是一个组。

重要的是要注意我正在使用 java.util.regex - 它没有 Perl 正则表达式中的 if/else 子句,但是可以使用组内的 or 语句的前瞻来实现相同的效果。我可以使用另一个支持 if/then/else 语句的库,但我不知道我可以使用它来实现我正在寻找的结果。

4

1 回答 1

1

使用 regex 解析 SQL 与使用 regex解析 HTML没有太大区别。换句话说,它不会起作用。这是无望的任务,现在停止。

相反,使用一些 SQL 解析器。例如,Perl 的SQL::Statement::Structure或 Java 的ANTLR

此外,由于您正在创建自己的数据库,因此值得看看其他 SQL 实现是如何做到的。我建议阅读PostgreSQLMySQL的源代码,看看它们是如何实现高级 SQL 解析的。

于 2013-09-04T03:48:51.937 回答