日期:2014-05-20  浏览次数:21191 次

〖编程擂台〗用C#去掉SQL语句中的注释
任务:用C#去掉SQL语句中的注释
环境:Microsoft SQL Server 查询分析器,或 Microsoft SQL Server Management Studio Express 的查询窗口。
要求:在下面 RemoveSqlComment() 方法中写语句,使得去掉注释前后的SQL语句在“查询分析器”中执行的结果一模一样。 

C# code
using System;
using System.Text.RegularExpressions;

class Program
{
  static string RemoveSqlComment(string sql)
  {
    // 在这里,发挥您有聪明才智。
  }
  
  static void Main()
  {
    string sql = Console.In.ReadToEnd();
    Console.WriteLine(RemoveSqlComment(sql));
  }
}



------解决方案--------------------
混点分先:
C# code
/// <summary>
/// 字符块
/// </summary>
public struct BlockInfo
{
    /// <summary>
    /// 起始标记
    /// </summary>
    public string start;
    /// <summary>
    /// 结束标记
    /// </summary>
    public string end;
    /// <summary>
    /// 替换后追加
    /// </summary>
    public string append;

    public BlockInfo(string start, string end, string append)
    {
        this.start = start;
        this.end = end;
        this.append = append;
    }
}

/// <summary>
/// 过滤字符块
/// </summary>
/// <param name="str">目标字符串</param>
/// <param name="blockInfos">字符块信息</param>
/// <param name="filter">过滤留下的区块</param>
/// <returns>返回被过后的字符串</returns>
public string FilterBlock(string str, BlockInfo[] blockInfos, int[] filter)
{
    if (blockInfos == null || blockInfos.Length <= 0) return str;
    if (filter == null || filter.Length <= 0) return str;
    StringBuilder result = new StringBuilder();
    int block = -1; // 区块类型 从0开始,-1表示无块状态
    for (int i = 0; i < str.Length; i++)
    {
        if (block == -1) // 无块状态
        {
            string temp = string.Empty;
            bool changed = false;
            for (int j = 0; j < blockInfos.Length; j++)
            {
                if (string.Compare(str, i, blockInfos[j].start, 
                    0, blockInfos[j].start.Length) == 0)
                {
                    temp = blockInfos[j].end;
                    block = j;
                    if (Array.IndexOf(filter, block) >= 0) // 需要出现
                        result.Append(blockInfos[block].start);
                    i += blockInfos[block].start.Length - 1;
                    changed = true;
                    break;
                }
            }
            if (!changed && Array.IndexOf(filter, block) >= 0) 
                result.Append(str[i]); // 区块没有变化
        }
        else // 其他状态
        {
            if (string.Compare(str, i, blockInfos[block].end,
                0, blockInfos[block].end.Length) == 0) // 状态结束
            {
                if (Array.IndexOf(filter, block) >= 0) // 需要出现
                    result.Append(blockInfos[block].end);
                else result.Append(blockInfos[block].append);
                i += blockInfos[block].end.Length - 1;
                block = -1;
            }
            else if (Array.IndexOf(filter, block) >= 0)
                result.Append(str[i]);
        }
    }

    return result.ToString();
}

private void Form1_Load(object sender, EventArgs e)
{
    string sql = @"
        SELECT '/* 你好 */ --' AS 注释, Field1 -- Zswang 路过
            FROM TableName
            WHERE Date = '2008-01-01' -- /*麻烦
            /*--
                奇怪
            --*/";
    sql = FilterBlock(sql, new BlockInfo[] { 
        new BlockInfo("'", "'", ""),
        new BlockInfo("/*", "*/", ""), 
        new BlockInfo("--", "\r\n", "\r\n")}, new int[] { -1, 0 });
    Console.Write(sql);
}

------解决方案--------------------