首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > .NET > C# >

〖编程擂台〗用C#去掉SQL语句中的注释,该怎么处理

2011-12-28 
〖编程擂台〗用C#去掉SQL语句中的注释任务:用C#去掉SQL语句中的注释。环境:Microsoft SQL Server 查询分析器,

〖编程擂台〗用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);}
[解决办法]


刚才忽略了5楼,呵呵。

有这情况。。。

SQL code
select/**/field1/**/from/**/table1
[解决办法]
我用堆栈。。。
select x -- abc 
原始串 操作栈 数据栈
SQL code
1 -- abc                                        select x 2 abc                          --             select x 3                               --             select x (发现操作栈栈顶是--操作符,舍弃abc)返回数据栈结果select x
[解决办法]
我的意见是不要只用一次正则!

首先确定注释的优先级
/*
--xx */ select xxxx /*
*/
这条语句能执行么?
能执行说明/**/优先级高
否则--行末优先级高

先把优先级高的注释正则掉。
然后正则优先级低的注释。

[解决办法]
不会 C#,用 Java 写了一个,我想正则表达式的语法基本上是一样的。

针对方案 7 的问题,我在替换字符串 $1 后面加了空格。

PS:实在想不出还有什么其他的情况了,呵呵。

Java code
public class Test {    public static void main(String args[]){        String str =             "SELECT '/* 你好 */ --' AS 注释, Field1 -- Zswang 路过\n" +            "FROM TableName\n" +            "WHERE Date = '2008-01-01' -- /*麻烦\n" +            "/*--\n" +            "    奇怪\n" +            "--*/\n" +            "declare @tt table(aid int primary/* 8*/ key identity/*--abd*/,aname varchar(200))--test)\n" +            "insert @tt (aname) values('abcdefg')\n" +            "insert @tt (aname) values('/*12345*/')\n" +            "insert @tt (aname) values('abc\n" +            "----\n" +            "--d--efg')insert @tt (aname) values('a/*bc\n" +            "----*/\n" +            "--d--efg')\n" +            "/*k\n" +            "kks*/\n" +            "/*lakjd */\n" +            "select * from @tt\n" +            "select/**/field1/**/from/**/table1\n" +            "/* \n" +            "  --xx */ select xxxx /* \n" +            "*/ \n";        String comment1 = "/\\*[^*]*\\*+(?:[^/*][^*]*\\*+)*/";        String comment2 = "--[^\n]*+";        String quote = "'[^']*(?:''[^']*)*'";        String addition = "[^'/-]";        String regex = "(" + addition + "+|" + quote + addition + "*)|" +                comment1 + "|" + comment2;        System.out.println(str);        System.out.println("================================================");        str = str.replaceAll(regex, "$1 ");        System.out.println(str);    }}
[解决办法]
未在查询分析器中测试 不知输错没有

SQL code
select '/*'+ field1 +'*/' as commentField1,'-- '+ field2 +'--'+ as lineField2,/* --/* pre 'text' */ feild3,/* /* 'abc*/'*//* TEST */field4
[解决办法]
探讨
改成这样能解决2楼出现的问题:


C# codereturn Regex.Replace(sql, @"(?ms)('(?:''|[^'])*')|--.*?(\r|$)|/\*.*?\*/", " $1");

[解决办法]
可以看下这个文章:
C#使用正则表达式实现语法分析引擎

热点排行