C#使用正则表达式将JSON字符串解析为DataTable
在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#数据处理技巧的资料请关注本站其它相关文章!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









