C#使用正则表达式将JSON字符串解析为DataTable

Ada
Ada
发布时间:2026-10-14 | 5人浏览过
原创

在C#开发中,有时需要将JSON数据直接转换为内存中的DataTable以便进行绑定或处理。本文将介绍一种基于正则表达式的方法,将符合特定结构的JSON字符串解析为标准的DataTable对象,包含完整的代码实现与输入输出格式说明。

核心实现逻辑

该方法的实现依赖于对JSON字符串结构的严格假设:JSON必须包含一个根对象,其中有一个键值对表示“表名”,其值是一个对象数组,每个对象代表表中的一行数据。解析过程分为三个阶段:识别表结构、初始化表架构、填充行数据。

第1步:定义解析函数入口

创建一个名为 JsonToDataTable 的公共静态方法,接收一个 string strJson 参数,并返回 System.Data.DataTable 实例。此方法是整个转换流程的核心容器。

代码如下:
#region 将 Json 解析成 DateTable
/// <summary>
/// 将 Json 解析成 DateTable。
/// Json 数据格式如: 
/// {table:[{column1:1,column2:2,column3:3},{column1:1,column2:2,column3:3}]}
/// </summary>
/// <param name="strJson">要解析的 Json 字符串</param>
/// <returns>返回 DateTable</returns>
public DataTable JsonToDataTable(string strJson)
{
    // 具体实现见下一步
}

第2步:提取表名并清理JSON内容

首先使用正则表达式提取作为表名的键值。原JSON字符串通常包裹着额外的文本,需要去除表名部分以及最外层的括号,仅保留内部的对象数组字符串,以便后续逐行解析。注意:这里的正则 (?<={)[^:]+(?=:) 用于匹配第一个冒号前的字符串作为表名。

代码如下:
// 取出表名
var rg = new Regex(@"(?<={)[^:]+(?=:)", RegexOptions.IgnoreCase);
string strName = rg.Match(strJson).Value;

// 验证是否成功提取到表名,防止空引用错误
if (string.IsNullOrEmpty(strName))
{
    throw new FormatException("无效的JSON格式:未找到表名标识。");
}

DataTable tb = null;

// 去除表名和外部包裹结构,只保留数据主体
// 注意:实际环境中建议先确认json起始位置更稳妥,此处依原逻辑简化
int startIndex = strJson.IndexOf('[') + 1;
int endIndex = strJson.LastIndexOf(']');
if (startIndex <= 0 || endIndex <= startIndex)
{
    throw new FormatException("无效的JSON格式:未找到数据数组。");
}
string dataContent = strJson.Substring(startIndex, endIndex - startIndex);

第3步:识别每一行数据并初始化表结构

遍历解析出的数据字符串,使用正则 (?<={)[^}]+(?=}) 匹配每一个对象块(即一行数据)。在遇到第一行时,创建 DataTable 实例,并根据该行内的所有键(Key)动态创建 DataColumn。此时完成表的架构定义(Schema)。

代码如下:
// 获取所有行的数据字符串
rg = new Regex(@"(?<={)[^}]+(?=})");
MatchCollection mc = rg.Matches(dataContent);

for (int i = 0; i < mc.Count; i++)
{
    string strRow = mc[i].Value;
    string[] strRows = strRow.Split(',');

    // 如果是第一行,创建表和列
    if (tb == null)
    {
        tb = new DataTable();
        tb.TableName = strName;
        foreach (string str in strRows)
        {
            var dc = new DataColumn();
            // 分割键值对,提取列名
            string[] strCell = str.Split(':');
            if (strCell.Length > 0)
            {
                dc.ColumnName = strCell[0].Trim().Replace("\"", "").Replace("'", "");
                tb.Columns.Add(dc);
            }
        }
        tb.AcceptChanges();
    }

第4步:填充数据行

对于每一行数据,创建一个新行 DataRow。遍历该行的所有列,再次使用 Split(':') 获取值部分,并移除多余的引号字符后填入对应的列索引中。最后将行添加到表中。

代码如下:
    // 增加内容
    DataRow dr = tb.NewRow();
    for (int j = 0; j < strRows.Length; j++)
    {
        string[] cellData = strRows[j].Split(':');
        if (cellData.Length > 1 && j < tb.Columns.Count)
        {
            // 替换掉可能存在的引号并赋值
            dr[j] = cellData[1].Trim().Replace("\"", "").Replace("'", "");
        }
    }
    tb.Rows.Add(dr);
    tb.AcceptChanges();
}

return tb;
}

JSON数据格式规范

要使上述方法正常工作,输入的JSON字符串必须符合特定的非标准格式。这种格式常见于某些遗留系统或特定API返回的数据结构中,它并非标准的JSON.stringify结果,而是省略了部分引号或使用了简写形式。

标准结构示例

正确的输入应包含一个顶层对象,其中键值为“table”(或其他自定义表名映射),值是一个由对象组成的数组。每个对象代表一行,属性名即为列名。

示例:
{
  table: [
    {
      column1: 1,
      column2: 2,
      column3: 3
    },
    {
      column1: 1,
      column2: 2,
      column3: 3
    }
  ]
}

实际应用案例

在实际元数据加载场景中,常会遇到类似以下结构的扁平化JSON。经过解析后,将生成一个包含 Code 和 Name 两列的 DataTable。

原始输入:
[{Code:MetaDataId,Name:MetaDataId},{Code:MetadataCode,Name:编号},{Code:SolutionName,Name:名称}]
格式化后的结构理解:
[
  {
    Code: MetaDataId,
    Name: MetaDataId
  }, 
  {
    Code: MetadataCode,
    Name: 编号
  }, 
  {
    Code: SolutionName,
    Name: 名称
  }
]

注意: 上述“原始输入”示例中缺少外层对象的键名包裹,如果直接使用原代码中的 IndexOf([) 逻辑,可能需要针对纯数组格式做额外适配。原代码主要针对带表名标识的格式优化。若遇到纯数组格式,建议先将其包装为 {tableName: [...]} 再传入,或修改正则提取逻辑以适应无头数组。

总结

通过正则表达式解析JSON到DataTable是一种轻量级且快速的方法,特别适用于格式固定且不依赖第三方库的场景。关键点在于确保输入JSON的结构与正则匹配规则一致,并在代码中做好基本的格式校验以防止运行时异常。以上就是C#将Json解析成DateTable的详细操作指南,更多关于C#数据处理技巧的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表