解析SQL语句的正则表达式

2024-04-20 07:30:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个IronPython脚本,它对一个sqlserver数据库执行一堆SQL语句。语句是实际上包含多个语句的大字符串,由“GO”关键字分隔。当它们从sqlmanagementstudio和其他一些工具中运行时,这是有效的,但在ADO中则不行。因此,我使用2.5“re”模块拆分字符串,如下所示:

splitter = re.compile(r'\bGO\b', re.IGNORECASE)
for script in splitter.split(scriptBlob):
    if(script):
        [... execute the query ...]

在注释或字符串中出现单词“go”的罕见情况下,这种情况会中断。我到底该怎么解决呢?i、 e.将此字符串正确解析为两个脚本:

^{pr2}$

编辑:

我搜索了更多,找到了以下SQL文档: http://msdn.microsoft.com/en-us/library/ms188037(SQL.90).aspx

事实证明,正如一些答案所暗示的,围棋必须走自己的路线。但是,它后面可以跟一个“count”整数,它将实际执行语句批处理很多次(以前有人实际使用过它吗??)它可以跟在同一行上的一行注释(但不是多行,我测试过了)所以magic regex看起来像:

"(?m)^\s*GO\s*\d*\s*$"

但这不能解释:

  • 结尾处可能有一个单行注释("--",后跟除换行符以外的任何字符)。在
  • 整行位于一个较大的多行注释中。在

我不关心捕捉“count”参数并使用它。现在我有了一些技术文档,我已经非常接近于编写这个“符合规范”的文档,而且再也不用担心它了。在


Tags: 字符串文档re脚本数据库gosqlcount
3条回答

如果GO总是在一条线上,您可以这样使用split:

#!/usr/bin/python

import re

sql = """-- this is a great database script!  go team go!
INSERT INTO myTable(stringColumn) VALUES ('go away!')
/*
  here are some comments that go with this script.
*/
GO 5 --this is a test
INSERT INTO myTable(stringColumn) VALUES ('this is the next script')"""

statements = re.split("(?m)^\s*GO\s*(?:[0-9]+)?\s*(?:--.*)?$", sql)

for statement in statements:
    print "the statement is\n%s\n" % (statement)
  • (?m)打开多行匹配,即^和{}将匹配行的开始和结束(而不是字符串的开始和结束)。在
  • ^匹配行的开头
  • \s*匹配零个或多个空白(空格、制表符等)
  • GO匹配文本GO
  • \s*与之前一样匹配
  • (?:[0-9]+)?匹配可选整数(可能有前导零)
  • \s*与之前一样匹配
  • (?:--.*)?匹配可选的行尾注释
  • $匹配行末尾

分割会消耗GO线,所以你不必担心。这将给您留下一个语句列表。在

这个修改过的拆分有一个问题:它在执行后不会返回数字,如果这很重要,我会说是时候转向某种形式的解析器了。在

“围棋”是不是总是在一条线上?你可以在“^GO$”上分开。在

因为您可以在注释中包含注释、嵌套注释、查询中的注释等,所以没有一种合理的方法来处理正则表达式。在

我只需设计以下脚本:

INSERT INTO table (name) VALUES (
-- GO NOW GO
'GO to GO /* GO */ GO' +
/* some comment 'go go go'
-- */ 'GO GO' /*
GO */
)

不提:

^{pr2}$

唯一的方法是构建一个有状态的解析器。一次读取一个字符,并且有一个标志,当它在注释/引号分隔的字符串/etc中时,它将被设置,当它结束时重置,因此代码可以在这些实例中忽略“GO”实例。在

相关问题 更多 >