我需要为 C# 构建一个正则表达式,以便捕获 select 子句中“from”关键字之后的所有表名。例如
.
.
.
SELECT field1, field2
FROM table1
WHERE condition1
.
.
.
SELECT field3, field4
FROM table2
WHERE condition2
.
.
.
我尝试读取的文件中有多个 select 子句,select 和 from 之间可以有任何字符(包括换行符、':'、'_' 和任何其他字符)。 我应该如何构建我的正则表达式以获取所有表名?
谢谢
编辑: 我找到了一种获取所有表名的方法。
\s*SELECT[^;]*FROM\s*(?<key>[^\n]*)
这可能会在某一天对某人有所帮助。 谢谢
最佳答案
除非所有查询都只有一个表并且没有有趣的评论业务,否则使用正则表达式是一个失败的提议。相反:
SET SHOWPLAN_ALL ON;
--All your queries here
参见 set showplan_all文档。
当我说正则表达式会变得复杂时,这就是我的意思。这些只是一些的注意事项:
您必须检测引用字符串的开头:
"
、'
和[
并忽略其中的所有字符直到正确终止。如果结束字符加倍则不要终止(即,'this is ''fun'', he said'
在is
之后不会停止)。您必须排除不在引号内的单行注释
--
,并在下一个 CRLF 处终止它们。注释中的引号不会像往常一样开始字符串。您必须排除不在引号内或单行注释内的多行注释(以
/*
开头),然后跳过其他所有内容除了终止符*/
。在您的正则表达式中,确保使用反斜杠\
转义*
字符。然后您必须找到具有正确单词边界的有效
FROM
子句(列名称SelfRom
或AfroMonkey
上没有错误匹配>,例如)。要正确终止 FROM 子句,您必须在看到任何关键字时停止捕获,包括
WHERE
、GROUP BY
、HAVING
、ORDER BY
和WITH
;并且由于 SQL 查询不需要有分号终止符;
那么您还必须在SELECT
、DBCC
、SET
、CREATE
、ALTER
、DROP
等等。但仅靠前两点还不够,因为如果您的查询如下所示:
SELECT * FROM MyTable T INNER JOIN ( SELECT * FROM YourTable Y WHERE Active = 1 ) X ON T.ID = Y.ID INNER JOIN AnotherTable A ON X.AID = A.AID
现在您必须解析括号并且当您看到任何这些关键字时不要停止捕获您的 FROM 子句。而且你必须跟踪你有多少括号,并一直忽略直到你有那么多。最后,您如何处理它们,因为派生表就像一个表——您是想要派生表的全文还是其中的表?
要做到这一切,您不能只从文本中第一个有效的 FROM
开始匹配,因为它可能在引号或注释中。您必须匹配从开头开始的所有文本,因为这是 Regex 确保您不会在不应该找到匹配项的地方找到匹配项的唯一方法。
这是我想出的,只是试图处理评论。甚至没有报价。它只会找到 from 子句,而不是其中的内容。另外,我们必须防止括号被捕获,这样在检查我们的捕获组以查找实际的 FROM 子句时,我们就不会搞得一团糟。
(?:(?:-(?!-)|/(?!\*)|f(?!rom)|[^-f/])|--[^\n]*\n|/\*(?:\*/)*\*/)*from()
而且它可能充满错误,一旦我玩了一下,我就不得不重新考虑整个事情,总而言之,这将是对时间的巨大浪费。
我认为您低估了完成这样的事情的难度。但是有一个非常可靠的解决方案!我上面给出的那个:让SQL Server为你解析一切。您可以轻松地解析返回的计划,因为它的结构使其变得简单。
关于c# - 如何在 C# 中使用正则表达式获取所有表名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13969009/