[英]How to get all table names with a regex in C#?
我需要为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 docs。
当我说正则表达式会很复杂时,这就是我的意思。 这些只是一些考虑因素:
您必须检测引用字符串的开头: "
, '
和[
并忽略内部的所有字符,直到正确终止。如果结束字符加倍,则不要终止(即'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为你解析一切。 您可以轻松地解析返回的计划,因为它的结构使其变得简单。
首先,我要看看这个教程: http : //www.codeproject.com/Articles/9099/The-30-Minute-Regex-Tutorial
看看像这样的正则表达式: ((?<=FROM )[^\\s]+)
这个正则表达式将在"FROM "
(包括空格)之后直接读取并在第一个空格处停止读取(^\\s)
如果你尝试这样的事情
foreach (Match m in Regex.Matches(input, @"((?<=FROM )[^\s]+)")
{
string output = m.Value;
}
编辑:
我对这个正则表达式并不是100%肯定。 如果你的名字末尾有一个换行符,这个woudl可能会更好地完成工作: @"((?<=FROM)[^\\n]+))
但你可能应该修剪输出,因为可能有一个空格在输出字符串的开头。
var input = "select name from Table1 where id =2";
var pattern = @"from\s*(.*?)\s*where"; // where car= is the first delimiter and ; is the second one
var result = Regex.Match(input, pattern).Groups[1].Value;
MessageBox.Show(result);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.