【C#工具类】过滤SQL文件里的注释

7 篇文章 0 订阅

SQL注释:

  1.单行注释:--单行注释

  2.多行注释:/*多行

        注释*/

1.用 字节数组 实现“跳过”注释

非常感谢我的良师益友@Caodenk提供了破题思路(字节数组就真的很香哇)~然后某陌补充了一丢丢,最后整理如下。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;

namespace Test
{
    public partial class skip : Component
    {

        public class Skip
        {


            public static (byte[], int) RemoveComment(byte[] sqlBuf, int Length)
            {
                byte[] retBuf = new byte[Length];
                int j = 0;
                for (int i = 0; i < Length;)
                {
                    if (sqlBuf[i] == '/' && sqlBuf[i + 1] == '*') //多行注释
                    {
                        i += 2;
                        SkipComment(ref i, sqlBuf);

                    }
                    else if (sqlBuf[i] == '-' && sqlBuf[i + 1] == '-') //单行注释
                    {
                        i += 2;
                        SkipComment1(ref i, sqlBuf);

                    }
                    else
                    {
                        retBuf[j] = sqlBuf[i];
                        ++j;
                        ++i;
                    }

                }


                return (retBuf, j);
            }

           public  static void SkipComment(ref int i, byte[] buf)
            {
                for (; ; i++)
                {
                    if (buf[i] == '*' && buf[i + 1] == '/')
                    {
                        i += 2;
                        break;
                    }

                }

            }

            public static void SkipComment1(ref int i, byte[] buf)
            {
                for (; ; i++)
                {
                    if (buf[i] == '\n' || buf[i] == '\r') //判定换行符即可
                    {
                        i += 2;
                        break;
                    }

                }

            }

        }     
     }
}

使用时调用方式:

                string filepath = @"TEST.sql";//原文件
                string filepath2 = @"test1.sql";//过滤注释后的文件
                using (var filestream = File.Open(filepath, FileMode.Open))
                {

                    byte[] buf = new byte[1024 * 1024 * 2];
                    int Length = filestream.Read(buf,0,buf.Length);
                    (var retbuf, int len) = skip.Skip.RemoveComment(buf, Length);
                    using (var createfile = File.Create(filepath2))
                    {
                        createfile.Write(retbuf, 0, len);

                    }


                }

上面的代码仅作测试Demo,这个思路差不多也可以处理大部分的基本情况了。当然,在此基础上也可以写“活”文件名称,写入完毕后也可以加入一些人性化的提示信息,等等。但是,在网上查阅资料的时候看到了一些“极端”的案例,比如:

@a varchar(10)='/*',                                        
@b datetime='*/',   

像这种情况上面的代码明显招架不住的……

另,我的良师益友后来又特别补充了一点:\r不是换行符,必须遇到\n才行(mac oc除外)在Windows中\r\n,linux时\n.故他的单行过滤是这么写的。

static void SkipSingleLineComment(ref int i,byte[] buf,int length)
{
    for(;;i++)
    {
        if(buf[i]=='\n')
        {
            i++;
            break;
        }
        if(i>=length) break;
    }
}

2.正则实现过滤注释

用正则过滤sql中的注释需要注意的是,读取文件时不能选用StreamReader的ReadLine()函数(逐行读取),因为在处理单行注释时只需判断是否是“--”开头即可,但是处理多行注释时就明显不适用了。解决办法是用StreamReader的ReadToEnd()方法读完文件,所以在良师益友的帮助下又有了正则的破题之法~

        string ClearMark(string input)
        {
            input =Regex.Replace(input, @"(/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+/)|'(?:[^']|'')*'|(--.*)","");     

            return input;
        }

这里的@代表后面的字符串原样匹配,故不需要写\\只用写一个\,但是*在正则中表示0或多个,所以对应的注释/**/就要写成/\*,同时上面的正则也去掉了''中的内容(这里过滤掉了表里的数据,如果需要保留SP的完整性就去掉这段过滤条件)。

使用时的调用方法:

string file = @"d:/test.sql";
ReadFile(file,@"d:/test3.sql");


        static void ReadFile(string file,string savepath)
        {
            string input=null;
            using(StreamReader sr = new StreamReader(file))
            {
                input = sr.ReadToEnd();
                input = ClearMark(input);
                using(StreamWriter sw = new StreamWriter(savepath))
                {
                    sw.Write(input);
                }

            }

        }

最后,再次感谢我的良师益友@Caodenk~~~

参考文档:

C# 注释&SQL注释 - 还可入梦 - 博客园

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值