Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/25.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用C和正则表达式从SQL select语句中删除别名_C#_.net_Regex - Fatal编程技术网

C# 使用C和正则表达式从SQL select语句中删除别名

C# 使用C和正则表达式从SQL select语句中删除别名,c#,.net,regex,C#,.net,Regex,我在学习正则表达式,我在玩它们。我建议自己做一个练习,其中有一个方法可以删除SQL Select语句中的列别名。这应该是这样的: 该方法可以删除SQL语句中的别名 选择带有AS关键字的语句: “选择ColumnA作为一个” 该方法可以删除SQL语句中的别名 不带AS的select语句 关键词:“选择列B” 该方法可以删除SQL语句中的别名 选择包含 “操作字符”如 串联操作字符: 选择“Hello”| |“world!”作为 “地狱世界” 到目前为止,我已经创建了两种只适用于特定情况的方法。下面

我在学习正则表达式,我在玩它们。我建议自己做一个练习,其中有一个方法可以删除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();
}