寻找 C# Regex 模式 SQL 表的特定解决方案

Posted

技术标签:

【中文标题】寻找 C# Regex 模式 SQL 表的特定解决方案【英文标题】:Looking for specific solution for C# Regex pattern SQL Table 【发布时间】:2016-10-02 08:20:09 【问题描述】:

我正在修改一个 C# 应用程序以遍历一堆 SQL 文件并将视图名称替换为其对应的表名称。

例如,名为“Item”的视图应替换为名为“Item_mst”的表。

我有一个映射文件,应用会查看该文件以确定要替换哪些表,如下所示:

VIEWNAME1,TABLENAME1_MST
VIEWNAME2,TABLENAME2_MST

问题是,有很多场景需要寻找,我在下面用一个示例 SQL 文件描述了它们。

Select 
    i.item <<Matches the Item table but is actually the name of the column, no replace
    ,dbo.item.u_m <<Matches the Item table with DBO., replace
    ,lot <<Matches the lot table but is actually the name of a column, no replace
    ,(Select top 1 cost from itemcost) as Cost <<itemcost is a table, replace
    ,(Select top 1 cost2 from dbo.itemcost) as Cost2 <<matches the itemcost table with dbo., replace
From 
    dbo.item i <<matches the item table with dbo.,replace
    cross join itemlot <<matches the itemlot table, replace

如您所见,有许多不同的场景,我很难编写正则表达式/查找和替换算法来可靠地捕捉每个场景。

我正在匹配 dbo.tablename 并替换那些很容易,这是我遇到麻烦的其余场景。有没有 REGEX 专家有什么想法?

这是一个代码sn-p:

//Replace all matched views with table names
for (int j = 0; j < viewCount.Count(); j++)

    //replace for "."
    curFileText = curFileText.Replace(".", "XXXPERIODXXX");
    curFileText = Regex.Replace(curFileText, "dboXXXPERIODXXX" + ViewTables[0, j] + "XXXPERIODXXX", "dboXXXPERIODXXX" + ViewTables[1, j] + "XXXPERIODXXX", RegexOptions.IgnoreCase);
    curFileText = curFileText.Replace("XXXPERIODXXX", ".");

    //replace for "newline"
    curFileText = curFileText.Replace(System.Environment.NewLine, "XXXNEWLINEXXX");
    curFileText = Regex.Replace(curFileText, ViewTables[0, j] + "XXXNEWLINEXXX", ViewTables[1, j] + "XXXNEWLINEXXX", RegexOptions.IgnoreCase);
    curFileText = curFileText.Replace("XXXNEWLINEXXX", System.Environment.NewLine);

    //Fix .column_mst spots
    curFileText = curFileText.Replace("dbo.", "XXXDBODOTXXX");
    curFileText = curFileText.Replace(".", "XXXDOTXXX");
    curFileText = Regex.Replace(curFileText, "XXXDOTXXX" + ViewTables[1, j], "XXXDOTXXX" + ViewTables[0, j], RegexOptions.IgnoreCase);
    curFileText = curFileText.Replace("XXXDOTXXX", ".");
    curFileText = curFileText.Replace("XXXDBODOTXXX", "dbo.");

    //replace for " "
    curFileText = curFileText.Replace(" ", "XXXSPACEXXX");
    curFileText = Regex.Replace(curFileText, "dbo." + ViewTables[0, j] + "XXXSPACEXXX", "dbo." + ViewTables[1, j] + "XXXSPACEXXX", RegexOptions.IgnoreCase);
    curFileText = curFileText.Replace("XXXSPACEXXX", " ");

【问题讨论】:

你想要做什么的描述和它的例子非常复杂。请显示输入和所需输出的示例,以便我们可以准确查看您想要的内容。然后我们也许可以解释这个解释。还请展示您到目前为止所做的尝试,并解释为什么它没有按照您的意愿行事。最后,那个“code sn-p”的目的是什么?它与问题有什么关系? 【参考方案1】:

为什么不反过来解决问题呢?根据您的 RDBMS,您可以使用类似 select table_name, view_definition from information_schema.views 的查询来获取所有视图名称和基础 SQL 的列表。每个视图的 SQL 中的某处将是一个 select ... from &lt;table name&gt; 语句,用于仅基于单个表的视图。将这些结果复制到 Sublime 或 Notepad++ 并使用简单的正则表达式(将 ([\w\W]+)(\s+from\s+)(\S+)([\w\W]+) 替换为 $3)导出与其基础表关联的视图名称列表,如下所示:vSomeView SomeTable vOtherView OtherTable

一旦你有了它,再次使用正则表达式生成一个.Replace 链,用.Replace("$1", "$3") 替换^([^ ])( )(\w\W)$。将 .Replace 链复制/粘贴到您用于执行此迁移的 C# 代码中。

【讨论】:

以上是关于寻找 C# Regex 模式 SQL 表的特定解决方案的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 regex.match 在 c# 中提取字符串的特定部分? [复制]

使用 Bash (sed?) 删除包含特定文本 (regex) 的多行 /* ... */ 样式注释

C# RegEx:忽略大小写...在模式中?

在 C# 中仅保留 Regex.Split 的匹配模式

使用 C# 正则表达式。问题是如何使用“=”

如何在 C# Regex 中使用lookbehind 来跳过重复前缀模式的匹配?