2013-02-12 81 views
0

我在文件中有以下SQL文本。目标是从文件中识别数据库表名。下面只是一个通用的例子,我正在寻找一个通用的解决方案,无论是在C#或Perl。我没有做很多的正则表达式的,因此,如果有人给我一开始复杂正则表达式C#或perl

select 
a.xyz, 
b.xyz,c.xyz, 
d.xyz 
from db1.test1 a 
inner join db2.test2 b 
on a.xyz = b.xyz 
inner join 
(
select a.xyz 
from db1.test3) as c 
on a.xyz=c.xyz 
left outer join db1.test4 d 
on c.xyz = d.xyz 

所以基本上,我需要自动找出在SQL中的所有表的名字,我将不胜感激。在这种情况下,测试1,测试2,测试3和测试4

我知道该模式是表名前面是“from”,“内部连接”,“左外连接”,然后数据库名称(如db1, db2等),然后是文字'。'和表名。

回答

2

这是C#代码,会发现比如你的表名:

var matches = Regex.Matches(yourString, @"(from|inner\s+join|left\s+outer\s+join)\s+[a-zA-Z0-9]+\s*\.\s*(?<table>[a-zA-Z0-9]+)(\s+[a-zA-Z0-9]+)?(\s*,\s*[a-zA-Z0-9]+\s*\.\s*(?<table>[a-zA-Z0-9]+)(\s+[a-zA-Z0-9]+)?)*", RegexOptions.ExplicitCapture); 
foreach (Match match in matches) 
{ 
    foreach (Capture capture in match.Groups["table"].Captures) 
    { 
     string tableName = capture.Value; 
    } 
} 

同样的正则表达式将至少让你在Perl中指出正确的方向,因为正则表达式主要是跨平台兼容性。

编辑:更新为(笨拙?)查找多个以逗号分隔的表格,并纳入Alan的建议,使用"table"来查找组并标记ExplicitCapture。如果遇到更多问题,您可能需要按照Regular expression to find all table names in a query中的建议进行操作,并找到SQL解析器,而不是试图使用正则表达式。

+0

感谢Tim,我可能会遇到另一种模式,例如,我可以使用类似于“from db1.test5,db1.test6” 这样的模式。在这种情况下,我想捕获但test5和test6。但是我看到我可以捕获test5(基于上面的代码)。有什么办法可以同时匹配test5和test6 – bcd 2013-02-13 00:59:27

+0

+1,但是你应该使用'Groups [“table”]'而不是'Groups [2]'。为了明白为什么,把它添加到你的正则表达式的末尾:'(?:\ s +(\ w +))?'。您应该发现'Group [2]'现在包含表别名('a','b'或'd'),'Groups [“table”]'与Groups [3]'相同。在同一个正则表达式中使用命名组和编号组绝不是一个好主意。实际上,如果您使用命名组,则应将ExplicitCapture标志设置为禁用编号组。 – 2013-02-13 01:08:32