C# 使用C和正则表达式从SQL select语句中删除别名
我在学习正则表达式,我在玩它们。我建议自己做一个练习,其中有一个方法可以删除SQL Select语句中的列别名。这应该是这样的: 该方法可以删除SQL语句中的别名 选择带有AS关键字的语句: “选择ColumnA作为一个” 该方法可以删除SQL语句中的别名 不带AS的select语句 关键词:“选择列B” 该方法可以删除SQL语句中的别名 选择包含 “操作字符”如 串联操作字符: 选择“Hello”| |“world!”作为 “地狱世界” 到目前为止,我已经创建了两种只适用于特定情况的方法。下面的代码总结了我所做的工作以及我所面临的问题C# 使用C和正则表达式从SQL select语句中删除别名,c#,.net,regex,C#,.net,Regex,我在学习正则表达式,我在玩它们。我建议自己做一个练习,其中有一个方法可以删除SQL Select语句中的列别名。这应该是这样的: 该方法可以删除SQL语句中的别名 选择带有AS关键字的语句: “选择ColumnA作为一个” 该方法可以删除SQL语句中的别名 不带AS的select语句 关键词:“选择列B” 该方法可以删除SQL语句中的别名 选择包含 “操作字符”如 串联操作字符: 选择“Hello”| |“world!”作为 “地狱世界” 到目前为止,我已经创建了两种只适用于特定情况的方法。下面
static void Main(string[] args)
{
string cols1 = "ColA as AliasA, ColB AliasB , As As ASasas, Asasasas as As";
string cols2 = "'aaa' || 'bbb' AS AliasC , 'ccc' || 'ddd' AliasD";
string answer1 = RemAliases(cols1); // Works fine
string answer2 = RemAliases2(cols2); // Works fine
string answer3 = RemAliases2(cols1); // Doesn't work
string answer4 = RemAliases(cols2); // Doesn't work
}
static string RemAliases2(string inputSql)
{
string pattern1 = @"(.+)\s+AS\s+\w+";
string replacement1 = "$1";
string pattern2 = @"(.+)\s+\w+";
string replacement2 = "$1";
string result = Regex.Replace(inputSql, pattern1, replacement1, RegexOptions.IgnoreCase);
result = Regex.Replace(result, pattern2, replacement2, RegexOptions.IgnoreCase);
return result;
}
static string RemAliases(string inputSql)
{
string pattern1 = @"(\w+)\s+AS\s+\w+";
string replacement1 = "$1";
string pattern2 = @"(\w+)\s+\w+";
string replacement2 = "$1";
string result = Regex.Replace(inputSql, pattern1, replacement1, RegexOptions.IgnoreCase);
result = Regex.Replace(result, pattern2, replacement2, RegexOptions.IgnoreCase);
return result;
}
我不希望“remalises”与“cols2”配合得很好,因为“\w+”与“|”字符不匹配。尽管如此,我还是希望《再婚2》也能和《cols1》配合得很好。有人能给我一些帮助,让我知道为什么“再婚2”对“cols1”案不起作用吗?请随意提供关于我使用这些正则表达式的方式的任何其他建议
提前谢谢
注:我使用的是.NET2.0。+\s+AS\s+\w+的一个问题是,+是贪婪的。这意味着它将继续运行,直到不再匹配任何字符,这意味着一个新行。如果你放一个?在+之后,它将使其变为惰性,因此它将在找到第一个空格后停止,因为该空格与\s匹配
下一个问题是这个问题。也匹配空白。所以,当你有ColB-AliasB,case时,它会一直运行,直到它得到一个AS来匹配正则表达式的下一部分。在本例中,这是下一组的一部分。因此,您最好像在RemAliases函数中那样使用\w+
这就是我目前所做的。如果我找到其他东西,我会在以后编辑更多内容。同时,由于您正在学习,当我需要编写一些正则表达式时,这里有一个非常好的参考资料,我通常会使用它:至于为什么RemAliases2对您的cols1不起作用,是因为。+是贪婪的-它需要尽可能多的时间 .+将占据整个线路。然后正则表达式引擎将后退一步,尝试匹配正则表达式的其余部分。因此,比赛将是:
(.+) --> "ColA as AliasA, ColB AliasB , As As ASasas, Asasasas"
\s+ --> " "
AS --> "as"
\s+ --> " "
\w+ --> "As"
在这里,我将正则表达式的每一部分分解为单独的行,并显示了字符串中在->之后的s内匹配的部分
您依次应用每个正则表达式,但它应用于整个字符串-碰巧,由于测试字符串中文本的顺序,它似乎可以工作-但它根本无法缩放
在这种情况下,一个可能更好的开端是:
(.+?)(\s+as\s+\w+\s*)(,|$)
我已将+更改为非贪婪+?,在别名列名之后但在逗号\s*之前添加了空格选项,并在行尾交替添加了逗号,以正确结束表达式,|$,这样您就可以对select子句中的每个字段重复多次
然而,这只进行了一次匹配,而不是多次匹配。注意,我知道正则表达式,但不知道C,所以我不能确切地说这在C中是如何工作的,但概念是相当一般的。您需要多次遍历字符串,或者使用全局标志调用函数。在Java中,您可以通过调用replaceAll而不是replace来实现这一点——我假设C具有类似的构造
全局应用,并在替换字符串中插入$1和$3将得到修改后的cols1:
可乐,可乐别名
那么,你就有了没有AS的情况,这就更难了 为了让正则表达式可靠地工作,您需要更加勤奋地拼写出它应该匹配的内容,而不是试图用。下面的解释相当冗长。这是我在构建正则表达式时遵循的思维过程 根据您的示例,您要么有一个标识符(如colA),要么有一个单引号字符串(如“aaa”| |“bbb”)的串联。您可以将标识符与\w+匹配,将字符串与“[^']*'?:\s*\\\\\\\\\\\\\s*'[^']*'*”匹配。我的字符串正则表达式允许连接任意数量的字符串,包括不连接,即仅一个带引号的字符串 要匹配这两个选项中的任何一个,我们可以使用\b\w+\s+|'[^']*'?:\s*\\\\\\\\\\\\\\\s*'[^']*'*\s*。我在标识符后面添加了\s+,因为它必须与后面的内容用空格隔开。对于连接的字符串,\s*使分隔空间可选 标识符或字符串后面可以选择跟随关键字As。如果关键字存在,则必须后跟空格。我们可以将其编码为\s+ 最后,所有这些后面都是另一个标识符。这个是 很容易与\w+匹配 综合起来,我们得到了这个正则表达式:
(\b\w+\s+|'[^']*'(?:\s*\|\|\s*'[^']*')*\s*)(As\s+)?\w+
我在第一部分周围安排了一个捕获小组。我们需要它来进行搜索和替换。仅用列名或字符串连接替换此正则表达式匹配可以有效地删除as部分。替换文本只需1美元
或在C中:
result = Regex.Replace(inputSql,
@"(\b\w+\s+|'[^']*'(?:\s*\|\|\s*'[^']*')*\s*)(As\s+)?\w+", "$1",
RegexOptions.IgnoreCase);
非正则表达式方法:
/// <summary>
/// Remove SQL aliases from a string of selects
/// </summary>
/// <param name="select">A string of selects</param>
/// <returns>A string of selects without any aliases</returns>
public static string RemoveAliases(string select)
{
string[] originalSelect = select.Split(',');
string[] newSelect = (string[])originalSelect.Clone();
string alias = " as ";
for (int i = 0; i < originalSelect.Length; i++)
{
int aliasIndex = originalSelect[i].IndexOf(alias, StringComparison.InvariantCultureIgnoreCase);
if (aliasIndex >= 0)
{
string withoutAlias = originalSelect[i].Substring(0, aliasIndex);
newSelect[i] = withoutAlias;
}
}
StringBuilder sbNoAliases = new StringBuilder();
for (int i = 0; i < newSelect.Length - 1; i++)
{
sbNoAliases.Append(newSelect[i] + ",");
}
sbNoAliases.Append(newSelect[newSelect.Length - 1]);
return sbNoAliases.ToString();
}