正则表达式提取SQL查询

时间:2013-05-21 14:27:25

标签: java regex matcher

是否有正则表达式从字符串中提取SQL查询?我 对验证任何SQL语法感兴趣,而只是提取一些SQL命令。这样可以灵活地解析给定的SQL文件/字符串。

给出以下SQL文件/字符串示例:

SELECT
    *
FROM
    test_table
WHERE
    test_row = 'Testing ; semicolon';

SELECT * FROM another_test_table;

INSERT INTO 
    table_name 
VALUES 
    (value1,'value which contains semicolon ;;;;',value3,...);

一些伪代码示例是:^(UPDATE|SELECT|INSERT INTO)(.*)(;)$。在未来,我希望用所有(可能的)命令扩展它。

  • 寻找与以下任何一个的起始匹配:(更新|选择|插入|输入)
  • 零个或多个any character(包括空格和换行符)
  • 停在;,分隔SQL查询。

每当通过正则表达式实现这一点时,以下java代码就能够提取所有SQL命令:

final String regex = "LOOKING_FOR_THIS_ONE";
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = p.matcher(content);

while (matcher.find()) {
  // matcher.group() now contains the full SQL command
}

提前致谢!

5 个答案:

答案 0 :(得分:2)

我首先要说这不是一个很好的方法,并强烈建议您找到另一种方法,最好在发表声明的地方正确标记,这样你就不会在这种情况下。

话虽如此,SQL要求它从以下之一开始; DELETESELECTWITHUPDATEINSERT INTO。它还要求输入以;结束。

我们可以使用它来获取与SQL匹配的所有序列:

final String regex = "^(INSERT INTO|UPDATE|SELECT|WITH|DELETE)(?:[^;']|(?:'[^']+'))+;\\s*$";
final Pattern p = Pattern.compile(regex, Pattern.MULTILINE | Pattern.DOTALL);

如果您希望在UPDATESELECT上过滤有效的SQL,则第1组现在会保留操作词。

请参阅正则表达式以及此处的洞穴:

https://regex101.com/r/dt9XTK/2

答案 1 :(得分:1)

只要分号是该行上的最后一个非空白字符,就可以“正确”匹配它。

final String regex = ^(SELECT|UPDATE|INSERT)[\s\S]+?\;\s*?$

final Pattern p = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = p.matcher(content);

答案 2 :(得分:0)

(?m)^(UPDATE|SELECT|INSERT INTO).*;$应该有效。这将扩展模式以匹配换行符。它应该能够遍历并找到所有SQL。

查看您提供的示例,它将匹配您的命令,直到;。您可以看到用于测试here的示例。

答案 3 :(得分:0)

如果您正在使用某种语言,请创建一个用于对您的字符串进行标记的词法分析器。使用JFlex,这是一个词法分析器生成器。它生成一个Java类,它根据特殊文件中指定的语法将字符串拆分为标记。从this file获取相关的语法规则。

解析是一个与标记化(或词法分析)不同的过程。在词法分析之后,如果词法分析还不够,你可能想要使用解析器生成器。

答案 4 :(得分:0)

SQL非常复杂,您需要使用上下文来查找所有语句,这意味着您无法使用正则表达式执行此操作。

例如:

SELECT Model FROM Product
WHERE ManufacturerID IN (SELECT ManufacturerID FROM Manufacturer 
WHERE Manufacturer = 'Dell')

(例子来自http://www.sql-tutorial.com/sql-nested-queries-sql-tutorial/)。嵌套查询可以多次嵌套,以不同的值开头等。如果,您可以为您感兴趣的子集编写正则表达式,那将是不可读的。

ANTLRSQL 2003 grammar可用(我还没试过)。