繁体   English   中英

如何在C#中使用正则表达式获取所有表名?

[英]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子句(例如,对列名称SelfRomAfroMonkey不进行错误匹配)。

  • 要正确终止FROM子句,您必须在看到任何关键字时停止捕获,包括WHEREGROUP BYHAVINGORDER BYWITH ; 并且因为SQL查询不需要具有分号终止符; 那么你还必须终止SELECTDBCCSETCREATEALTERDROP等等。

  • 但即使前两点本身也不够,因为如果您的查询如下所示:

     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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM