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

C#如何不区分大小写解析拆分SQL字符串的各组成部分

问题解决实现方案

你当前用String.Split的实现有两个明显缺陷:一是默认大小写敏感,无法匹配不同大小写形式的SQL关键字;二是硬编码单词分隔符的方式无法支持group by、order by这类多词关键字,还可能把字段值、表名字段名里包含的关键字误识别为拆分点。

推荐实现:基于正则匹配子句位置切片

这个方案可以同时解决大小写不敏感、多关键字支持、避免误匹配的问题,实现逻辑是先识别所有子句关键字在SQL中的位置,再按位置切片提取对应子句内容,不需要手动拼接丢失的关键字。

首先引入需要的命名空间:

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

提取方法代码:

public static Dictionary<string, string> ExtractSqlClauses(string sql)
{
    // 关键字按长度从长到短排列,优先匹配长关键字,避免短关键字提前截断长匹配(比如优先匹配group by而非单独的group)
    var sqlKeywords = new[] 
    { 
        "select", "from", "where", "group by", "having", "order by", 
        "left join", "right join", "inner join", "join", "limit", "offset" 
    };
    // 正则加单词边界\b,避免把表名、字段名、字段值里的关键字片段误识别为子句开头,比如表名from_user不会被误判为from子句
    var matchPattern = $@"\b({string.Join("|", sqlKeywords)})\b";
    var matches = Regex.Matches(
        sql, 
        matchPattern, 
        RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.Multiline
    );

    var result = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
    if (matches.Count == 0) return result;

    for (int i = 0; i < matches.Count; i++)
    {
        var current = matches[i];
        int clauseStart = current.Index;
        int clauseEnd = i == matches.Count - 1 ? sql.Length : matches[i + 1].Index;
        // 提取子句内容并去除首尾多余空白
        var clauseContent = sql.Substring(clauseStart, clauseEnd - clauseStart).Trim();
        // key统一转小写,取值时不区分大小写
        result[current.Value.ToLower()] = clauseContent;
    }
    return result;
}

调用示例

var testSql = @"select Id, Name from Order where Id ='8675' and Name ='Test' group by Id, Name order by Id desc";
var clauses = ExtractSqlClauses(testSql);

// 取值不区分key大小写,不管SQL里写的是from/From/FROM都能正常取到
var selectPart = clauses["select"]; // 返回:select Id, Name
var fromPart = clauses["from"];     // 返回:from Order
var wherePart = clauses["where"];   // 返回:where Id ='8675' and Name ='Test'
var groupPart = clauses["group by"];// 返回:group by Id, Name
var orderPart = clauses["order by"];// 返回:order by Id desc

不推荐的简化方案(仅适配简单场景)

如果你用的是.NET Core 2.1+/.NET 5+版本,String.Split本身支持传入大小写比较规则,但是这个方案无法处理多词关键字,也无法避免字段值中包含关键字导致的误拆分,仅适合非常简单的固定SQL场景:

var str = @"select Id, Name from Order where Id ='8675' and Name ='Test'";
String[] separators = { "from", "where" };
// 传入StringComparison.OrdinalIgnoreCase实现忽略大小写拆分
String[] strlist = str.Split(separators, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries, StringComparison.OrdinalIgnoreCase);

注意:如果需要处理包含子查询、嵌套语句、SQL注释的复杂SQL,不建议用字符串匹配的方式提取子句,应该使用专门的SQL语法解析库处理,避免匹配错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 02:24:14