You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C# Regex替换SQL脚本注释时匹配范围超出预期如何解决?

问题原因

你写的正则[-][-][^\\]*\r\n在C#中出现匹配范围超出预期,核心有两个问题:

  1. C#字符串的转义规则和正则引擎的转义规则存在冲突:你写的[^\\]在C#字符串中实际会被解析为匹配所有不是反斜杠的字符,而*是贪婪匹配符,会一直匹配到整个字符串末尾的最后一个\r\n为止,自然会把第一条注释之后所有不含反斜杠的内容全部删除。
  2. 你之前在VSCode、正则测试网站测试时使用的是正则原义,没有考虑C#字符串的转义逻辑,所以测试结果和实际运行结果不一致。

修复方案

1. 正确删除单行SQL注释的写法

使用带@前缀的逐字字符串避免C#字符串转义的干扰,正则规则调整为匹配--开头到行尾为止的内容:

// 匹配--开头到换行符之前的所有内容,开启多行模式匹配每行的注释
script = Regex.Replace(script, @"--.*?$", " ", RegexOptions.Multiline);

2. 修正换行/制表符替换的正则

你之前写的"\."逻辑完全错误,会匹配所有点号,正确的写法是匹配回车、换行、制表符:

// 替换换行、回车、制表符为空格
script = Regex.Replace(script, @"[\r\n\t]", " ");

3. 拆分GO执行逻辑优化

拆分后需要过滤空字符串,避免执行空SQL抛出异常:

List<string> scriptParts = Regex.Split(script, @"\bGO\b", RegexOptions.IgnoreCase)
    .Where(s => !string.IsNullOrWhiteSpace(s))
    .ToList();

完整修正后代码

List<string> resourceNames = new List<string> {"MyTrigger.sql" };

DbContext context = GetDbContext(contextType);
try {
    context.Database.OpenConnection();
    resourceNames.ForEach(resourceName => {
        string script = ReadEmbeddedResource(resourceName);
        // 删除单行SQL注释
        script = Regex.Replace(script, @"--.*?$", " ", RegexOptions.Multiline);
        // 替换换行、回车、制表符为空格
        script = Regex.Replace(script, @"[\r\n\t]", " ");
        // 按GO拆分,过滤空段后独立执行每一段
        List<string> scriptParts = Regex.Split(script, @"\bGO\b", RegexOptions.IgnoreCase)
            .Where(s => !string.IsNullOrWhiteSpace(s))
            .ToList();
        scriptParts.ForEach(scriptPart => context.Database.ExecuteSqlRaw(scriptPart));
    });
} finally {
    context.Database.CloseConnection();
}

内容的提问来源于stack exchange,提问作者Rhett Newton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 05:36:00