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

如何在C#中修正正则,匹配未被WHEN及任意空格前置的EMP_ID?

解决方案:修正正则或使用SQL语法解析器

一、修正正则表达式

原正则(?<!WHEN\s)EMP_ID的问题在于仅能排除WHEN后紧跟单个空格的情况,无法处理多空格、制表符等空白字符,同时未考虑排除WHERE子句中的匹配(如果这是你的需求)。

1. 处理WHEN后任意空白字符

将负向后行断言改为匹配WHEN后跟任意数量的空白字符,同时开启大小写不敏感(SQL关键字不区分大小写):

string pattern = @"(?<!WHEN\s*)EMP_ID";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);

这样无论WHEN后是1个还是多个空格、制表符,后面的EMP_ID都不会被匹配。

2. 同时排除WHERE子句中的EMP_ID

如果需要同时排除WHERE后的EMP_ID,可以扩展断言:

string pattern = @"(?<!(WHEN|WHERE)\s*)EMP_ID";
Regex regex = new Regex(pattern, RegexOptions.IgnoreCase);

3. 边缘情况补充

如果要避免匹配字符串、注释中的EMP_ID,可以进一步扩展正则,但正则处理SQL始终存在局限性,比如无法应对嵌套结构等复杂场景。

二、更可靠的方案:使用SQL语法解析器

正则处理SQL容易遇到各种边缘场景(比如嵌套CASE、字符串中的列名、注释等),推荐使用专业的SQL解析库Microsoft.SqlServer.TransactSql.ScriptDom:

  1. 安装NuGet包:Microsoft.SqlServer.TransactSql.ScriptDom
  2. 编写解析代码:
using Microsoft.SqlServer.TransactSql.ScriptDom;

public static List<string> GetTargetSelectColumns(string sql)
{
    List<string> targetColumns = new List<string>();
    TSql160Parser parser = new TSql160Parser(false);
    IList<ParseError> parseErrors = new List<ParseError>();
    
    using (StringReader reader = new StringReader(sql))
    {
        TSqlFragment sqlFragment = parser.Parse(reader, out parseErrors);
        if (parseErrors.Count > 0)
        {
            // 此处可添加解析错误的处理逻辑
            return targetColumns;
        }

        if (sqlFragment is TSqlBatch batch)
        {
            foreach (var statement in batch.Statements)
            {
                if (statement is SelectStatement selectStmt)
                {
                    if (selectStmt.QueryExpression is QuerySpecification querySpec)
                    {
                        foreach (var selectElement in querySpec.SelectElements)
                        {
                            if (selectElement is SelectScalarScalarExpression scalarExpr)
                            {
                                if (scalarExpr.Expression is ColumnReferenceExpr columnRef)
                                {
                                    // 处理单部分列名(如EMP_ID)
                                    if (columnRef.MultiPartIdentifier.Identifiers.Count == 1)
                                    {
                                        string columnName = columnRef.MultiPartIdentifier.Identifiers[0].Value;
                                        if (columnName.Equals("EMP_ID", StringComparison.OrdinalIgnoreCase))
                                        {
                                            targetColumns.Add(columnName);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return targetColumns;
}

这个方法可以精准识别SELECT列表中的目标列名,完全避免正则的误匹配问题,适合复杂SQL场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:20:23